diff --git a/.changes/api-tray-menu.md b/.changes/api-tray-menu.md new file mode 100644 index 00000000000..2071bcca177 --- /dev/null +++ b/.changes/api-tray-menu.md @@ -0,0 +1,5 @@ +--- +'@tauri-apps/api': 'minor:feat' +--- + +Add `tray` and `menu` modules to create and manage tray icons and menus from Javascript. diff --git a/.github/workflows/lint-js.yml b/.github/workflows/lint-js.yml index 587d8285d4a..5fe27a62c6c 100644 --- a/.github/workflows/lint-js.yml +++ b/.github/workflows/lint-js.yml @@ -49,6 +49,9 @@ jobs: - name: install deps via yarn working-directory: ./tooling/api/ run: yarn + - name: run ts:check + working-directory: ./tooling/api/ + run: yarn ts:check - name: run lint working-directory: ./tooling/api/ run: yarn lint diff --git a/.husky/pre-commit b/.husky/pre-commit index 3050d5d43f9..7178a541726 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -11,7 +11,7 @@ if [ -z "$(git diff --name-only tooling/api)" ]; then else cd tooling/api yarn format - yarn lint-fix + yarn lint:fix cd ../.. fi diff --git a/.scripts/ci/check-license-header.js b/.scripts/ci/check-license-header.js index a3a8b32c0f3..40da761054b 100644 --- a/.scripts/ci/check-license-header.js +++ b/.scripts/ci/check-license-header.js @@ -13,6 +13,8 @@ SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: MIT` const bundlerLicense = '// Copyright 2016-2019 Cargo-Bundle developers ' +const denoLicense = + '// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.' const extensions = ['.rs', '.js', '.ts', '.yml', '.swift', '.kt'] const ignore = [ @@ -43,7 +45,8 @@ async function checkFile(file) { line.length === 0 || line.startsWith('#!') || line.startsWith('// swift-tools-version:') || - line === bundlerLicense + line === bundlerLicense || + line === denoLicense ) { continue } diff --git a/core/tauri-macros/src/lib.rs b/core/tauri-macros/src/lib.rs index 3962b1012d1..104dd31a6aa 100644 --- a/core/tauri-macros/src/lib.rs +++ b/core/tauri-macros/src/lib.rs @@ -16,6 +16,7 @@ use proc_macro::TokenStream; use syn::{parse_macro_input, DeriveInput}; mod command; +mod menu; mod mobile; mod runtime; @@ -89,3 +90,64 @@ pub fn default_runtime(attributes: TokenStream, input: TokenStream) -> TokenStre let input = parse_macro_input!(input as DeriveInput); runtime::default_runtime(attributes, input).into() } + +/// Accepts a closure-like syntax to call arbitrary code on a menu item +/// after matching against `kind` and retrieving it from `resources_table` using `rid`. +/// +/// You can optionally pass a third parameter to select which item kinds +/// to match against, by providing a `|` separated list of item kinds +/// ```ignore +/// do_menu_item!(|i| i.set_text(text), Check | Submenu); +/// ``` +/// You could also provide a negated list +/// ```ignore +/// do_menu_item!(|i| i.set_text(text), !Check); +/// do_menu_item!(|i| i.set_text(text), !Check | !Submenu); +/// ``` +/// but you can't have mixed negations and positive kinds. +/// ```ignore +/// do_menu_item!(|i| i.set_text(text), !Check | Submeun); +/// ``` +/// +/// #### Example +/// +/// ```ignore +/// let rid = 23; +/// let kind = ItemKind::Check; +/// let resources_table = app.manager.resources_table(); +/// do_menu_item!(|i| i.set_text(text)) +/// ``` +/// which will expand into: +/// ```ignore +/// let rid = 23; +/// let kind = ItemKind::Check; +/// let resources_table = app.manager.resources_table(); +/// match kind { +/// ItemKind::Submenu => { +/// let i = resources_table.get::>(rid)?; +/// i.set_text(text) +/// } +/// ItemKind::MenuItem => { +/// let i = resources_table.get::>(rid)?; +/// i.set_text(text) +/// } +/// ItemKind::Predefined => { +/// let i = resources_table.get::>(rid)?; +/// i.set_text(text) +/// } +/// ItemKind::Check => { +/// let i = resources_table.get::>(rid)?; +/// i.set_text(text) +/// } +/// ItemKind::Icon => { +/// let i = resources_table.get::>(rid)?; +/// i.set_text(text) +/// } +/// _ => unreachable!(), +/// } +/// ``` +#[proc_macro] +pub fn do_menu_item(input: TokenStream) -> TokenStream { + let tokens = parse_macro_input!(input as menu::DoMenuItemInput); + menu::do_menu_item(tokens).into() +} diff --git a/core/tauri-macros/src/menu.rs b/core/tauri-macros/src/menu.rs new file mode 100644 index 00000000000..2e6dc9bd871 --- /dev/null +++ b/core/tauri-macros/src/menu.rs @@ -0,0 +1,118 @@ +// Copyright 2019-2023 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use proc_macro2::{Ident, Span, TokenStream}; +use quote::quote; +use syn::{ + parse::{Parse, ParseStream}, + punctuated::Punctuated, + Expr, Token, +}; + +pub struct DoMenuItemInput { + resources_table: Ident, + rid: Ident, + kind: Ident, + var: Ident, + expr: Expr, + kinds: Vec, +} + +#[derive(Clone)] +struct NegatedIdent(bool, Ident); + +impl Parse for NegatedIdent { + fn parse(input: ParseStream) -> syn::Result { + let t = input.parse::(); + let i: Ident = input.parse()?; + Ok(NegatedIdent(t.is_ok(), i)) + } +} + +impl Parse for DoMenuItemInput { + fn parse(input: ParseStream) -> syn::Result { + let resources_table: Ident = input.parse()?; + let _: Token![,] = input.parse()?; + let rid: Ident = input.parse()?; + let _: Token![,] = input.parse()?; + let kind: Ident = input.parse()?; + let _: Token![,] = input.parse()?; + let _: Token![|] = input.parse()?; + let var: Ident = input.parse()?; + let _: Token![|] = input.parse()?; + let expr: Expr = input.parse()?; + let _: syn::Result = input.parse(); + let kinds = Punctuated::::parse_terminated(input)?; + + Ok(Self { + resources_table, + rid, + kind, + var, + expr, + kinds: kinds.into_iter().collect(), + }) + } +} + +pub fn do_menu_item(input: DoMenuItemInput) -> TokenStream { + let DoMenuItemInput { + rid, + resources_table, + kind, + expr, + var, + mut kinds, + } = input; + + let defaults = vec![ + NegatedIdent(false, Ident::new("Submenu", Span::call_site())), + NegatedIdent(false, Ident::new("MenuItem", Span::call_site())), + NegatedIdent(false, Ident::new("Predefined", Span::call_site())), + NegatedIdent(false, Ident::new("Check", Span::call_site())), + NegatedIdent(false, Ident::new("Icon", Span::call_site())), + ]; + + if kinds.is_empty() { + kinds.extend(defaults.clone()); + } + + let has_negated = kinds.iter().any(|n| n.0); + + if has_negated { + kinds.extend(defaults); + kinds.sort_by(|a, b| a.1.cmp(&b.1)); + kinds.dedup_by(|a, b| a.1 == b.1); + } + + let (kinds, types): (Vec, Vec) = kinds + .into_iter() + .filter_map(|nident| { + if nident.0 { + None + } else { + match nident.1 { + i if i == "MenuItem" => Some((i, Ident::new("MenuItem", Span::call_site()))), + i if i == "Submenu" => Some((i, Ident::new("Submenu", Span::call_site()))), + i if i == "Predefined" => Some((i, Ident::new("PredefinedMenuItem", Span::call_site()))), + i if i == "Check" => Some((i, Ident::new("CheckMenuItem", Span::call_site()))), + i if i == "Icon" => Some((i, Ident::new("IconMenuItem", Span::call_site()))), + _ => None, + } + } + }) + .unzip(); + + quote! { + match #kind { + #( + ItemKind::#kinds => { + let #var = #resources_table.get::<#types>(#rid)?; + #expr + } + )* + _ => unreachable!(), + } + } +} diff --git a/core/tauri/Cargo.toml b/core/tauri/Cargo.toml index e6f5abff15a..931f54cc0af 100644 --- a/core/tauri/Cargo.toml +++ b/core/tauri/Cargo.toml @@ -73,8 +73,8 @@ ico = { version = "0.3.0", optional = true } http-range = { version = "0.1.5", optional = true } [target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\", target_os = \"windows\", target_os = \"macos\"))".dependencies] -muda = { version = "0.10", default-features = false } -tray-icon = { version = "0.10", default-features = false, optional = true } +muda = { version = "0.10", default-features = false, features = [ "serde" ] } +tray-icon = { version = "0.10", default-features = false, features = [ "serde" ], optional = true } [target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies] gtk = { version = "0.18", features = [ "v3_24" ] } diff --git a/core/tauri/scripts/bundle.global.js b/core/tauri/scripts/bundle.global.js index da2051dd67b..62903986339 100644 --- a/core/tauri/scripts/bundle.global.js +++ b/core/tauri/scripts/bundle.global.js @@ -1 +1 @@ -var __TAURI_IIFE__=function(e){"use strict";function t(e,t,n,i){if("a"===n&&!i)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!i:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===n?i:"a"===n?i.call(e):i?i.value:t.get(e)}var n;function i(e,t=!1){return window.__TAURI_INTERNALS__.transformCallback(e,t)}"function"==typeof SuppressedError&&SuppressedError;class r{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,n.set(this,(()=>{})),this.id=i((e=>{t(this,n,"f").call(this,e)}))}set onmessage(e){!function(e,t,n,i,r){if("m"===i)throw new TypeError("Private method is not writable");if("a"===i&&!r)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");"a"===i?r.call(e,n):r?r.value=n:t.set(e,n)}(this,n,e,"f")}get onmessage(){return t(this,n,"f")}toJSON(){return`__CHANNEL__:${this.id}`}}n=new WeakMap;class a{constructor(e,t,n){this.plugin=e,this.event=t,this.channelId=n}async unregister(){return l(`plugin:${this.plugin}|remove_listener`,{event:this.event,channelId:this.channelId})}}async function l(e,t={},n){return window.__TAURI_INTERNALS__.invoke(e,t,n)}var s=Object.freeze({__proto__:null,Channel:r,PluginListener:a,addPluginListener:async function(e,t,n){const i=new r;return i.onmessage=n,l(`plugin:${e}|register_listener`,{event:t,handler:i}).then((()=>new a(e,t,i.id)))},convertFileSrc:function(e,t="asset"){return window.__TAURI_INTERNALS__.convertFileSrc(e,t)},invoke:l,transformCallback:i});var o,u=Object.freeze({__proto__:null,getName:async function(){return l("plugin:app|name")},getTauriVersion:async function(){return l("plugin:app|tauri_version")},getVersion:async function(){return l("plugin:app|version")},hide:async function(){return l("plugin:app|app_hide")},show:async function(){return l("plugin:app|app_show")}});async function c(e,t){await l("plugin:event|unlisten",{event:e,eventId:t})}async function p(e,t,n){return l("plugin:event|listen",{event:e,windowLabel:n?.target,handler:i(t)}).then((t=>async()=>c(e,t)))}async function h(e,t,n){return p(e,(n=>{t(n),c(e,n.id).catch((()=>{}))}),n)}async function d(e,t,n){await l("plugin:event|emit",{event:e,windowLabel:n?.target,payload:t})}!function(e){e.WINDOW_RESIZED="tauri://resize",e.WINDOW_MOVED="tauri://move",e.WINDOW_CLOSE_REQUESTED="tauri://close-requested",e.WINDOW_CREATED="tauri://window-created",e.WINDOW_DESTROYED="tauri://destroyed",e.WINDOW_FOCUS="tauri://focus",e.WINDOW_BLUR="tauri://blur",e.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",e.WINDOW_THEME_CHANGED="tauri://theme-changed",e.WINDOW_FILE_DROP="tauri://file-drop",e.WINDOW_FILE_DROP_HOVER="tauri://file-drop-hover",e.WINDOW_FILE_DROP_CANCELLED="tauri://file-drop-cancelled",e.MENU="tauri://menu"}(o||(o={}));var y=Object.freeze({__proto__:null,get TauriEvent(){return o},emit:d,listen:p,once:h});class w{constructor(e,t){this.type="Logical",this.width=e,this.height=t}}class _{constructor(e,t){this.type="Physical",this.width=e,this.height=t}toLogical(e){return new w(this.width/e,this.height/e)}}class g{constructor(e,t){this.type="Logical",this.x=e,this.y=t}}class b{constructor(e,t){this.type="Physical",this.x=e,this.y=t}toLogical(e){return new g(this.x/e,this.y/e)}}var f,m,v=Object.freeze({__proto__:null,LogicalPosition:g,LogicalSize:w,PhysicalPosition:b,PhysicalSize:_});!function(e){e[e.Critical=1]="Critical",e[e.Informational=2]="Informational"}(f||(f={}));class D{constructor(e){this._preventDefault=!1,this.event=e.event,this.windowLabel=e.windowLabel,this.id=e.id}preventDefault(){this._preventDefault=!0}isPreventDefault(){return this._preventDefault}}function E(){return new A(window.__TAURI_INTERNALS__.metadata.currentWindow.label,{skip:!0})}function L(){return window.__TAURI_INTERNALS__.metadata.windows.map((e=>new A(e.label,{skip:!0})))}!function(e){e.None="none",e.Normal="normal",e.Indeterminate="indeterminate",e.Paused="paused",e.Error="error"}(m||(m={}));const I=["tauri://created","tauri://error"];class A{constructor(e,t={}){this.label=e,this.listeners=Object.create(null),t?.skip||l("plugin:window|create",{options:{...t,label:e}}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static getByLabel(e){return L().some((t=>t.label===e))?new A(e,{skip:!0}):null}static getCurrent(){return E()}static getAll(){return L()}static async getFocusedWindow(){for(const e of L())if(await e.isFocused())return e;return null}async listen(e,t){return this._handleTauriEvent(e,t)?Promise.resolve((()=>{const n=this.listeners[e];n.splice(n.indexOf(t),1)})):p(e,t,{target:this.label})}async once(e,t){return this._handleTauriEvent(e,t)?Promise.resolve((()=>{const n=this.listeners[e];n.splice(n.indexOf(t),1)})):h(e,t,{target:this.label})}async emit(e,t){if(I.includes(e)){for(const n of this.listeners[e]||[])n({event:e,id:-1,windowLabel:this.label,payload:t});return Promise.resolve()}return d(e,t,{target:this.label})}_handleTauriEvent(e,t){return!!I.includes(e)&&(e in this.listeners?this.listeners[e].push(t):this.listeners[e]=[t],!0)}async scaleFactor(){return l("plugin:window|scale_factor",{label:this.label})}async innerPosition(){return l("plugin:window|inner_position",{label:this.label}).then((({x:e,y:t})=>new b(e,t)))}async outerPosition(){return l("plugin:window|outer_position",{label:this.label}).then((({x:e,y:t})=>new b(e,t)))}async innerSize(){return l("plugin:window|inner_size",{label:this.label}).then((({width:e,height:t})=>new _(e,t)))}async outerSize(){return l("plugin:window|outer_size",{label:this.label}).then((({width:e,height:t})=>new _(e,t)))}async isFullscreen(){return l("plugin:window|is_fullscreen",{label:this.label})}async isMinimized(){return l("plugin:window|is_minimized",{label:this.label})}async isMaximized(){return l("plugin:window|is_maximized",{label:this.label})}async isFocused(){return l("plugin:window|is_focused",{label:this.label})}async isDecorated(){return l("plugin:window|is_decorated",{label:this.label})}async isResizable(){return l("plugin:window|is_resizable",{label:this.label})}async isMaximizable(){return l("plugin:window|is_maximizable",{label:this.label})}async isMinimizable(){return l("plugin:window|is_minimizable",{label:this.label})}async isClosable(){return l("plugin:window|is_closable",{label:this.label})}async isVisible(){return l("plugin:window|is_visible",{label:this.label})}async title(){return l("plugin:window|title",{label:this.label})}async theme(){return l("plugin:window|theme",{label:this.label})}async center(){return l("plugin:window|center",{label:this.label})}async requestUserAttention(e){let t=null;return e&&(t=e===f.Critical?{type:"Critical"}:{type:"Informational"}),l("plugin:window|request_user_attention",{label:this.label,value:t})}async setResizable(e){return l("plugin:window|set_resizable",{label:this.label,value:e})}async setMaximizable(e){return l("plugin:window|set_maximizable",{label:this.label,value:e})}async setMinimizable(e){return l("plugin:window|set_minimizable",{label:this.label,value:e})}async setClosable(e){return l("plugin:window|set_closable",{label:this.label,value:e})}async setTitle(e){return l("plugin:window|set_title",{label:this.label,value:e})}async maximize(){return l("plugin:window|maximize",{label:this.label})}async unmaximize(){return l("plugin:window|unmaximize",{label:this.label})}async toggleMaximize(){return l("plugin:window|toggle_maximize",{label:this.label})}async minimize(){return l("plugin:window|minimize",{label:this.label})}async unminimize(){return l("plugin:window|unminimize",{label:this.label})}async show(){return l("plugin:window|show",{label:this.label})}async hide(){return l("plugin:window|hide",{label:this.label})}async close(){return l("plugin:window|close",{label:this.label})}async setDecorations(e){return l("plugin:window|set_decorations",{label:this.label,value:e})}async setShadow(e){return l("plugin:window|set_shadow",{label:this.label,value:e})}async setEffects(e){return l("plugin:window|set_effects",{label:this.label,value:e})}async clearEffects(){return l("plugin:window|set_effects",{label:this.label,value:null})}async setAlwaysOnTop(e){return l("plugin:window|set_always_on_top",{label:this.label,value:e})}async setAlwaysOnBottom(e){return l("plugin:window|set_always_on_bottom",{label:this.label,value:e})}async setContentProtected(e){return l("plugin:window|set_content_protected",{label:this.label,value:e})}async setSize(e){if(!e||"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `size` argument must be either a LogicalSize or a PhysicalSize instance");return l("plugin:window|set_size",{label:this.label,value:{type:e.type,data:{width:e.width,height:e.height}}})}async setMinSize(e){if(e&&"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `size` argument must be either a LogicalSize or a PhysicalSize instance");return l("plugin:window|set_min_size",{label:this.label,value:e?{type:e.type,data:{width:e.width,height:e.height}}:null})}async setMaxSize(e){if(e&&"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `size` argument must be either a LogicalSize or a PhysicalSize instance");return l("plugin:window|set_max_size",{label:this.label,value:e?{type:e.type,data:{width:e.width,height:e.height}}:null})}async setPosition(e){if(!e||"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `position` argument must be either a LogicalPosition or a PhysicalPosition instance");return l("plugin:window|set_position",{label:this.label,value:{type:e.type,data:{x:e.x,y:e.y}}})}async setFullscreen(e){return l("plugin:window|set_fullscreen",{label:this.label,value:e})}async setFocus(){return l("plugin:window|set_focus",{label:this.label})}async setIcon(e){return l("plugin:window|set_icon",{label:this.label,value:"string"==typeof e?e:Array.from(e)})}async setSkipTaskbar(e){return l("plugin:window|set_skip_taskbar",{label:this.label,value:e})}async setCursorGrab(e){return l("plugin:window|set_cursor_grab",{label:this.label,value:e})}async setCursorVisible(e){return l("plugin:window|set_cursor_visible",{label:this.label,value:e})}async setCursorIcon(e){return l("plugin:window|set_cursor_icon",{label:this.label,value:e})}async setCursorPosition(e){if(!e||"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `position` argument must be either a LogicalPosition or a PhysicalPosition instance");return l("plugin:window|set_cursor_position",{label:this.label,value:{type:e.type,data:{x:e.x,y:e.y}}})}async setIgnoreCursorEvents(e){return l("plugin:window|set_ignore_cursor_events",{label:this.label,value:e})}async startDragging(){return l("plugin:window|start_dragging",{label:this.label})}async setProgressBar(e){return l("plugin:window|set_progress_bar",{label:this.label,value:e})}async onResized(e){return this.listen(o.WINDOW_RESIZED,(t=>{t.payload=N(t.payload),e(t)}))}async onMoved(e){return this.listen(o.WINDOW_MOVED,(t=>{t.payload=W(t.payload),e(t)}))}async onCloseRequested(e){return this.listen(o.WINDOW_CLOSE_REQUESTED,(t=>{const n=new D(t);Promise.resolve(e(n)).then((()=>{if(!n.isPreventDefault())return this.close()}))}))}async onFocusChanged(e){const t=await this.listen(o.WINDOW_FOCUS,(t=>{e({...t,payload:!0})})),n=await this.listen(o.WINDOW_BLUR,(t=>{e({...t,payload:!1})}));return()=>{t(),n()}}async onScaleChanged(e){return this.listen(o.WINDOW_SCALE_FACTOR_CHANGED,e)}async onMenuClicked(e){return this.listen(o.MENU,e)}async onFileDropEvent(e){const t=await this.listen(o.WINDOW_FILE_DROP,(t=>{e({...t,payload:{type:"drop",paths:t.payload.paths,position:W(t.payload.position)}})})),n=await this.listen(o.WINDOW_FILE_DROP_HOVER,(t=>{e({...t,payload:{type:"hover",paths:t.payload.paths,position:W(t.payload.position)}})})),i=await this.listen(o.WINDOW_FILE_DROP_CANCELLED,(t=>{e({...t,payload:{type:"cancel"}})}));return()=>{t(),n(),i()}}async onThemeChanged(e){return this.listen(o.WINDOW_THEME_CHANGED,e)}}var z,C;function P(e){return null===e?null:{name:e.name,scaleFactor:e.scaleFactor,position:W(e.position),size:N(e.size)}}function W(e){return new b(e.x,e.y)}function N(e){return new _(e.width,e.height)}!function(e){e.AppearanceBased="appearanceBased",e.Light="light",e.Dark="dark",e.MediumLight="mediumLight",e.UltraDark="ultraDark",e.Titlebar="titlebar",e.Selection="selection",e.Menu="menu",e.Popover="popover",e.Sidebar="sidebar",e.HeaderView="headerView",e.Sheet="sheet",e.WindowBackground="windowBackground",e.HudWindow="hudWindow",e.FullScreenUI="fullScreenUI",e.Tooltip="tooltip",e.ContentBackground="contentBackground",e.UnderWindowBackground="underWindowBackground",e.UnderPageBackground="underPageBackground",e.Mica="mica",e.Blur="blur",e.Acrylic="acrylic",e.Tabbed="tabbed",e.TabbedDark="tabbedDark",e.TabbedLight="tabbedLight"}(z||(z={})),function(e){e.FollowsWindowActiveState="followsWindowActiveState",e.Active="active",e.Inactive="inactive"}(C||(C={}));var T,O=Object.freeze({__proto__:null,CloseRequestedEvent:D,get Effect(){return z},get EffectState(){return C},LogicalPosition:g,LogicalSize:w,PhysicalPosition:b,PhysicalSize:_,get ProgressBarStatus(){return m},get UserAttentionType(){return f},Window:A,availableMonitors:async function(){return l("plugin:window|available_monitors").then((e=>e.map(P)))},currentMonitor:async function(){return l("plugin:window|current_monitor").then(P)},getAll:L,getCurrent:E,primaryMonitor:async function(){return l("plugin:window|primary_monitor").then(P)}});!function(e){e[e.Audio=1]="Audio",e[e.Cache=2]="Cache",e[e.Config=3]="Config",e[e.Data=4]="Data",e[e.LocalData=5]="LocalData",e[e.Document=6]="Document",e[e.Download=7]="Download",e[e.Picture=8]="Picture",e[e.Public=9]="Public",e[e.Video=10]="Video",e[e.Resource=11]="Resource",e[e.Temp=12]="Temp",e[e.AppConfig=13]="AppConfig",e[e.AppData=14]="AppData",e[e.AppLocalData=15]="AppLocalData",e[e.AppCache=16]="AppCache",e[e.AppLog=17]="AppLog",e[e.Desktop=18]="Desktop",e[e.Executable=19]="Executable",e[e.Font=20]="Font",e[e.Home=21]="Home",e[e.Runtime=22]="Runtime",e[e.Template=23]="Template"}(T||(T={}));var R=Object.freeze({__proto__:null,get BaseDirectory(){return T},appCacheDir:async function(){return l("plugin:path|resolve_directory",{directory:T.AppCache})},appConfigDir:async function(){return l("plugin:path|resolve_directory",{directory:T.AppConfig})},appDataDir:async function(){return l("plugin:path|resolve_directory",{directory:T.AppData})},appLocalDataDir:async function(){return l("plugin:path|resolve_directory",{directory:T.AppLocalData})},appLogDir:async function(){return l("plugin:path|resolve_directory",{directory:T.AppLog})},audioDir:async function(){return l("plugin:path|resolve_directory",{directory:T.Audio})},basename:async function(e,t){return l("plugin:path|basename",{path:e,ext:t})},cacheDir:async function(){return l("plugin:path|resolve_directory",{directory:T.Cache})},configDir:async function(){return l("plugin:path|resolve_directory",{directory:T.Config})},dataDir:async function(){return l("plugin:path|resolve_directory",{directory:T.Data})},delimiter:function(){return window.__TAURI_INTERNALS__.plugins.path.delimiter},desktopDir:async function(){return l("plugin:path|resolve_directory",{directory:T.Desktop})},dirname:async function(e){return l("plugin:path|dirname",{path:e})},documentDir:async function(){return l("plugin:path|resolve_directory",{directory:T.Document})},downloadDir:async function(){return l("plugin:path|resolve_directory",{directory:T.Download})},executableDir:async function(){return l("plugin:path|resolve_directory",{directory:T.Executable})},extname:async function(e){return l("plugin:path|extname",{path:e})},fontDir:async function(){return l("plugin:path|resolve_directory",{directory:T.Font})},homeDir:async function(){return l("plugin:path|resolve_directory",{directory:T.Home})},isAbsolute:async function(e){return l("plugin:path|isAbsolute",{path:e})},join:async function(...e){return l("plugin:path|join",{paths:e})},localDataDir:async function(){return l("plugin:path|resolve_directory",{directory:T.LocalData})},normalize:async function(e){return l("plugin:path|normalize",{path:e})},pictureDir:async function(){return l("plugin:path|resolve_directory",{directory:T.Picture})},publicDir:async function(){return l("plugin:path|resolve_directory",{directory:T.Public})},resolve:async function(...e){return l("plugin:path|resolve",{paths:e})},resolveResource:async function(e){return l("plugin:path|resolve_directory",{directory:T.Resource,path:e})},resourceDir:async function(){return l("plugin:path|resolve_directory",{directory:T.Resource})},runtimeDir:async function(){return l("plugin:path|resolve_directory",{directory:T.Runtime})},sep:function(){return window.__TAURI_INTERNALS__.plugins.path.sep},tempDir:async function(e){return l("plugin:path|resolve_directory",{directory:T.Temp})},templateDir:async function(){return l("plugin:path|resolve_directory",{directory:T.Template})},videoDir:async function(){return l("plugin:path|resolve_directory",{directory:T.Video})}});return e.app=u,e.dpi=v,e.event=y,e.path=R,e.primitives=s,e.window=O,e}({});window.__TAURI__=__TAURI_IIFE__; +var __TAURI_IIFE__=function(e){"use strict";function n(e,n,t,i){if("a"===t&&!i)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof n?e!==n||!i:!n.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===t?i:"a"===t?i.call(e):i?i.value:n.get(e)}function t(e,n,t,i,r){if("m"===i)throw new TypeError("Private method is not writable");if("a"===i&&!r)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof n?e!==n||!r:!n.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===i?r.call(e,t):r?r.value=t:n.set(e,t),t}var i;function r(e,n=!1){return window.__TAURI_INTERNALS__.transformCallback(e,n)}"function"==typeof SuppressedError&&SuppressedError;class a{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,i.set(this,(()=>{})),this.id=r((e=>{n(this,i,"f").call(this,e)}))}set onmessage(e){t(this,i,e,"f")}get onmessage(){return n(this,i,"f")}toJSON(){return`__CHANNEL__:${this.id}`}}i=new WeakMap;class s{constructor(e,n,t){this.plugin=e,this.event=n,this.channelId=t}async unregister(){return l(`plugin:${this.plugin}|remove_listener`,{event:this.event,channelId:this.channelId})}}async function l(e,n={},t){return window.__TAURI_INTERNALS__.invoke(e,n,t)}var o=Object.freeze({__proto__:null,Channel:a,PluginListener:s,addPluginListener:async function(e,n,t){const i=new a;return i.onmessage=t,l(`plugin:${e}|register_listener`,{event:n,handler:i}).then((()=>new s(e,n,i.id)))},convertFileSrc:function(e,n="asset"){return window.__TAURI_INTERNALS__.convertFileSrc(e,n)},invoke:l,transformCallback:r});var u,c=Object.freeze({__proto__:null,getName:async function(){return l("plugin:app|name")},getTauriVersion:async function(){return l("plugin:app|tauri_version")},getVersion:async function(){return l("plugin:app|version")},hide:async function(){return l("plugin:app|app_hide")},show:async function(){return l("plugin:app|app_show")}});async function d(e,n){await l("plugin:event|unlisten",{event:e,eventId:n})}async function p(e,n,t){return l("plugin:event|listen",{event:e,windowLabel:t?.target,handler:r(n)}).then((n=>async()=>d(e,n)))}async function h(e,n,t){return p(e,(t=>{n(t),d(e,t.id).catch((()=>{}))}),t)}async function y(e,n,t){await l("plugin:event|emit",{event:e,windowLabel:t?.target,payload:n})}!function(e){e.WINDOW_RESIZED="tauri://resize",e.WINDOW_MOVED="tauri://move",e.WINDOW_CLOSE_REQUESTED="tauri://close-requested",e.WINDOW_CREATED="tauri://window-created",e.WINDOW_DESTROYED="tauri://destroyed",e.WINDOW_FOCUS="tauri://focus",e.WINDOW_BLUR="tauri://blur",e.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",e.WINDOW_THEME_CHANGED="tauri://theme-changed",e.WINDOW_FILE_DROP="tauri://file-drop",e.WINDOW_FILE_DROP_HOVER="tauri://file-drop-hover",e.WINDOW_FILE_DROP_CANCELLED="tauri://file-drop-cancelled"}(u||(u={}));var g=Object.freeze({__proto__:null,get TauriEvent(){return u},emit:y,listen:p,once:h});class w{constructor(e,n){this.type="Logical",this.width=e,this.height=n}}class _{constructor(e,n){this.type="Physical",this.width=e,this.height=n}toLogical(e){return new w(this.width/e,this.height/e)}}class m{constructor(e,n){this.type="Logical",this.x=e,this.y=n}}class b{constructor(e,n){this.type="Physical",this.x=e,this.y=n}toLogical(e){return new m(this.x/e,this.y/e)}}var f,v,k=Object.freeze({__proto__:null,LogicalPosition:m,LogicalSize:w,PhysicalPosition:b,PhysicalSize:_});!function(e){e[e.Critical=1]="Critical",e[e.Informational=2]="Informational"}(f||(f={}));class D{constructor(e){this._preventDefault=!1,this.event=e.event,this.windowLabel=e.windowLabel,this.id=e.id}preventDefault(){this._preventDefault=!0}isPreventDefault(){return this._preventDefault}}function A(){return new L(window.__TAURI_INTERNALS__.metadata.currentWindow.label,{skip:!0})}function E(){return window.__TAURI_INTERNALS__.metadata.windows.map((e=>new L(e.label,{skip:!0})))}!function(e){e.None="none",e.Normal="normal",e.Indeterminate="indeterminate",e.Paused="paused",e.Error="error"}(v||(v={}));const I=["tauri://created","tauri://error"];class L{constructor(e,n={}){this.label=e,this.listeners=Object.create(null),n?.skip||l("plugin:window|create",{options:{...n,label:e}}).then((async()=>this.emit("tauri://created"))).catch((async e=>this.emit("tauri://error",e)))}static getByLabel(e){return E().some((n=>n.label===e))?new L(e,{skip:!0}):null}static getCurrent(){return A()}static getAll(){return E()}static async getFocusedWindow(){for(const e of E())if(await e.isFocused())return e;return null}async listen(e,n){return this._handleTauriEvent(e,n)?Promise.resolve((()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)})):p(e,n,{target:this.label})}async once(e,n){return this._handleTauriEvent(e,n)?Promise.resolve((()=>{const t=this.listeners[e];t.splice(t.indexOf(n),1)})):h(e,n,{target:this.label})}async emit(e,n){if(I.includes(e)){for(const t of this.listeners[e]||[])t({event:e,id:-1,windowLabel:this.label,payload:n});return Promise.resolve()}return y(e,n,{target:this.label})}_handleTauriEvent(e,n){return!!I.includes(e)&&(e in this.listeners?this.listeners[e].push(n):this.listeners[e]=[n],!0)}async scaleFactor(){return l("plugin:window|scale_factor",{label:this.label})}async innerPosition(){return l("plugin:window|inner_position",{label:this.label}).then((({x:e,y:n})=>new b(e,n)))}async outerPosition(){return l("plugin:window|outer_position",{label:this.label}).then((({x:e,y:n})=>new b(e,n)))}async innerSize(){return l("plugin:window|inner_size",{label:this.label}).then((({width:e,height:n})=>new _(e,n)))}async outerSize(){return l("plugin:window|outer_size",{label:this.label}).then((({width:e,height:n})=>new _(e,n)))}async isFullscreen(){return l("plugin:window|is_fullscreen",{label:this.label})}async isMinimized(){return l("plugin:window|is_minimized",{label:this.label})}async isMaximized(){return l("plugin:window|is_maximized",{label:this.label})}async isFocused(){return l("plugin:window|is_focused",{label:this.label})}async isDecorated(){return l("plugin:window|is_decorated",{label:this.label})}async isResizable(){return l("plugin:window|is_resizable",{label:this.label})}async isMaximizable(){return l("plugin:window|is_maximizable",{label:this.label})}async isMinimizable(){return l("plugin:window|is_minimizable",{label:this.label})}async isClosable(){return l("plugin:window|is_closable",{label:this.label})}async isVisible(){return l("plugin:window|is_visible",{label:this.label})}async title(){return l("plugin:window|title",{label:this.label})}async theme(){return l("plugin:window|theme",{label:this.label})}async center(){return l("plugin:window|center",{label:this.label})}async requestUserAttention(e){let n=null;return e&&(n=e===f.Critical?{type:"Critical"}:{type:"Informational"}),l("plugin:window|request_user_attention",{label:this.label,value:n})}async setResizable(e){return l("plugin:window|set_resizable",{label:this.label,value:e})}async setMaximizable(e){return l("plugin:window|set_maximizable",{label:this.label,value:e})}async setMinimizable(e){return l("plugin:window|set_minimizable",{label:this.label,value:e})}async setClosable(e){return l("plugin:window|set_closable",{label:this.label,value:e})}async setTitle(e){return l("plugin:window|set_title",{label:this.label,value:e})}async maximize(){return l("plugin:window|maximize",{label:this.label})}async unmaximize(){return l("plugin:window|unmaximize",{label:this.label})}async toggleMaximize(){return l("plugin:window|toggle_maximize",{label:this.label})}async minimize(){return l("plugin:window|minimize",{label:this.label})}async unminimize(){return l("plugin:window|unminimize",{label:this.label})}async show(){return l("plugin:window|show",{label:this.label})}async hide(){return l("plugin:window|hide",{label:this.label})}async close(){return l("plugin:window|close",{label:this.label})}async setDecorations(e){return l("plugin:window|set_decorations",{label:this.label,value:e})}async setShadow(e){return l("plugin:window|set_shadow",{label:this.label,value:e})}async setEffects(e){return l("plugin:window|set_effects",{label:this.label,value:e})}async clearEffects(){return l("plugin:window|set_effects",{label:this.label,value:null})}async setAlwaysOnTop(e){return l("plugin:window|set_always_on_top",{label:this.label,value:e})}async setAlwaysOnBottom(e){return l("plugin:window|set_always_on_bottom",{label:this.label,value:e})}async setContentProtected(e){return l("plugin:window|set_content_protected",{label:this.label,value:e})}async setSize(e){if(!e||"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `size` argument must be either a LogicalSize or a PhysicalSize instance");return l("plugin:window|set_size",{label:this.label,value:{type:e.type,data:{width:e.width,height:e.height}}})}async setMinSize(e){if(e&&"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `size` argument must be either a LogicalSize or a PhysicalSize instance");return l("plugin:window|set_min_size",{label:this.label,value:e?{type:e.type,data:{width:e.width,height:e.height}}:null})}async setMaxSize(e){if(e&&"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `size` argument must be either a LogicalSize or a PhysicalSize instance");return l("plugin:window|set_max_size",{label:this.label,value:e?{type:e.type,data:{width:e.width,height:e.height}}:null})}async setPosition(e){if(!e||"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `position` argument must be either a LogicalPosition or a PhysicalPosition instance");return l("plugin:window|set_position",{label:this.label,value:{type:e.type,data:{x:e.x,y:e.y}}})}async setFullscreen(e){return l("plugin:window|set_fullscreen",{label:this.label,value:e})}async setFocus(){return l("plugin:window|set_focus",{label:this.label})}async setIcon(e){return l("plugin:window|set_icon",{label:this.label,value:"string"==typeof e?e:Array.from(e)})}async setSkipTaskbar(e){return l("plugin:window|set_skip_taskbar",{label:this.label,value:e})}async setCursorGrab(e){return l("plugin:window|set_cursor_grab",{label:this.label,value:e})}async setCursorVisible(e){return l("plugin:window|set_cursor_visible",{label:this.label,value:e})}async setCursorIcon(e){return l("plugin:window|set_cursor_icon",{label:this.label,value:e})}async setCursorPosition(e){if(!e||"Logical"!==e.type&&"Physical"!==e.type)throw new Error("the `position` argument must be either a LogicalPosition or a PhysicalPosition instance");return l("plugin:window|set_cursor_position",{label:this.label,value:{type:e.type,data:{x:e.x,y:e.y}}})}async setIgnoreCursorEvents(e){return l("plugin:window|set_ignore_cursor_events",{label:this.label,value:e})}async startDragging(){return l("plugin:window|start_dragging",{label:this.label})}async setProgressBar(e){return l("plugin:window|set_progress_bar",{label:this.label,value:e})}async onResized(e){return this.listen(u.WINDOW_RESIZED,(n=>{n.payload=x(n.payload),e(n)}))}async onMoved(e){return this.listen(u.WINDOW_MOVED,(n=>{n.payload=T(n.payload),e(n)}))}async onCloseRequested(e){return this.listen(u.WINDOW_CLOSE_REQUESTED,(n=>{const t=new D(n);Promise.resolve(e(t)).then((()=>{if(!t.isPreventDefault())return this.close()}))}))}async onFocusChanged(e){const n=await this.listen(u.WINDOW_FOCUS,(n=>{e({...n,payload:!0})})),t=await this.listen(u.WINDOW_BLUR,(n=>{e({...n,payload:!1})}));return()=>{n(),t()}}async onScaleChanged(e){return this.listen(u.WINDOW_SCALE_FACTOR_CHANGED,e)}async onFileDropEvent(e){const n=await this.listen(u.WINDOW_FILE_DROP,(n=>{e({...n,payload:{type:"drop",paths:n.payload.paths,position:T(n.payload.position)}})})),t=await this.listen(u.WINDOW_FILE_DROP_HOVER,(n=>{e({...n,payload:{type:"hover",paths:n.payload.paths,position:T(n.payload.position)}})})),i=await this.listen(u.WINDOW_FILE_DROP_CANCELLED,(n=>{e({...n,payload:{type:"cancel"}})}));return()=>{n(),t(),i()}}async onThemeChanged(e){return this.listen(u.WINDOW_THEME_CHANGED,e)}}var S,P;function C(e){return null===e?null:{name:e.name,scaleFactor:e.scaleFactor,position:T(e.position),size:x(e.size)}}function T(e){return new b(e.x,e.y)}function x(e){return new _(e.width,e.height)}!function(e){e.AppearanceBased="appearanceBased",e.Light="light",e.Dark="dark",e.MediumLight="mediumLight",e.UltraDark="ultraDark",e.Titlebar="titlebar",e.Selection="selection",e.Menu="menu",e.Popover="popover",e.Sidebar="sidebar",e.HeaderView="headerView",e.Sheet="sheet",e.WindowBackground="windowBackground",e.HudWindow="hudWindow",e.FullScreenUI="fullScreenUI",e.Tooltip="tooltip",e.ContentBackground="contentBackground",e.UnderWindowBackground="underWindowBackground",e.UnderPageBackground="underPageBackground",e.Mica="mica",e.Blur="blur",e.Acrylic="acrylic",e.Tabbed="tabbed",e.TabbedDark="tabbedDark",e.TabbedLight="tabbedLight"}(S||(S={})),function(e){e.FollowsWindowActiveState="followsWindowActiveState",e.Active="active",e.Inactive="inactive"}(P||(P={}));var F,z=Object.freeze({__proto__:null,CloseRequestedEvent:D,get Effect(){return S},get EffectState(){return P},LogicalPosition:m,LogicalSize:w,PhysicalPosition:b,PhysicalSize:_,get ProgressBarStatus(){return v},get UserAttentionType(){return f},Window:L,availableMonitors:async function(){return l("plugin:window|available_monitors").then((e=>e.map(C)))},currentMonitor:async function(){return l("plugin:window|current_monitor").then(C)},getAll:E,getCurrent:A,primaryMonitor:async function(){return l("plugin:window|primary_monitor").then(C)}});!function(e){e[e.Audio=1]="Audio",e[e.Cache=2]="Cache",e[e.Config=3]="Config",e[e.Data=4]="Data",e[e.LocalData=5]="LocalData",e[e.Document=6]="Document",e[e.Download=7]="Download",e[e.Picture=8]="Picture",e[e.Public=9]="Public",e[e.Video=10]="Video",e[e.Resource=11]="Resource",e[e.Temp=12]="Temp",e[e.AppConfig=13]="AppConfig",e[e.AppData=14]="AppData",e[e.AppLocalData=15]="AppLocalData",e[e.AppCache=16]="AppCache",e[e.AppLog=17]="AppLog",e[e.Desktop=18]="Desktop",e[e.Executable=19]="Executable",e[e.Font=20]="Font",e[e.Home=21]="Home",e[e.Runtime=22]="Runtime",e[e.Template=23]="Template"}(F||(F={}));var R,W=Object.freeze({__proto__:null,get BaseDirectory(){return F},appCacheDir:async function(){return l("plugin:path|resolve_directory",{directory:F.AppCache})},appConfigDir:async function(){return l("plugin:path|resolve_directory",{directory:F.AppConfig})},appDataDir:async function(){return l("plugin:path|resolve_directory",{directory:F.AppData})},appLocalDataDir:async function(){return l("plugin:path|resolve_directory",{directory:F.AppLocalData})},appLogDir:async function(){return l("plugin:path|resolve_directory",{directory:F.AppLog})},audioDir:async function(){return l("plugin:path|resolve_directory",{directory:F.Audio})},basename:async function(e,n){return l("plugin:path|basename",{path:e,ext:n})},cacheDir:async function(){return l("plugin:path|resolve_directory",{directory:F.Cache})},configDir:async function(){return l("plugin:path|resolve_directory",{directory:F.Config})},dataDir:async function(){return l("plugin:path|resolve_directory",{directory:F.Data})},delimiter:function(){return window.__TAURI_INTERNALS__.plugins.path.delimiter},desktopDir:async function(){return l("plugin:path|resolve_directory",{directory:F.Desktop})},dirname:async function(e){return l("plugin:path|dirname",{path:e})},documentDir:async function(){return l("plugin:path|resolve_directory",{directory:F.Document})},downloadDir:async function(){return l("plugin:path|resolve_directory",{directory:F.Download})},executableDir:async function(){return l("plugin:path|resolve_directory",{directory:F.Executable})},extname:async function(e){return l("plugin:path|extname",{path:e})},fontDir:async function(){return l("plugin:path|resolve_directory",{directory:F.Font})},homeDir:async function(){return l("plugin:path|resolve_directory",{directory:F.Home})},isAbsolute:async function(e){return l("plugin:path|isAbsolute",{path:e})},join:async function(...e){return l("plugin:path|join",{paths:e})},localDataDir:async function(){return l("plugin:path|resolve_directory",{directory:F.LocalData})},normalize:async function(e){return l("plugin:path|normalize",{path:e})},pictureDir:async function(){return l("plugin:path|resolve_directory",{directory:F.Picture})},publicDir:async function(){return l("plugin:path|resolve_directory",{directory:F.Public})},resolve:async function(...e){return l("plugin:path|resolve",{paths:e})},resolveResource:async function(e){return l("plugin:path|resolve_directory",{directory:F.Resource,path:e})},resourceDir:async function(){return l("plugin:path|resolve_directory",{directory:F.Resource})},runtimeDir:async function(){return l("plugin:path|resolve_directory",{directory:F.Runtime})},sep:function(){return window.__TAURI_INTERNALS__.plugins.path.sep},tempDir:async function(){return l("plugin:path|resolve_directory",{directory:F.Temp})},templateDir:async function(){return l("plugin:path|resolve_directory",{directory:F.Template})},videoDir:async function(){return l("plugin:path|resolve_directory",{directory:F.Video})}});class N{get rid(){return n(this,R,"f")}constructor(e){R.set(this,void 0),t(this,R,e,"f")}async close(){return l("plugin:resources|close",{rid:this.rid})}}R=new WeakMap;class O extends N{constructor(e,n){super(e),this.id=n}static async new(e){e?.menu&&(e.menu=[e.menu.rid,e.menu.kind]),e?.icon&&(e.icon="string"==typeof e.icon?e.icon:Array.from(e.icon));const n=new a;return e?.action&&(n.onmessage=e.action,delete e.action),l("plugin:tray|new",{options:e??{},handler:n}).then((([e,n])=>new O(e,n)))}async setIcon(e){let n=null;return e&&(n="string"==typeof e?e:Array.from(e)),l("plugin:tray|set_icon",{rid:this.rid,icon:n})}async setMenu(e){return e&&(e=[e.rid,e.kind]),l("plugin:tray|set_menu",{rid:this.rid,menu:e})}async setTooltip(e){return l("plugin:tray|set_tooltip",{rid:this.rid,tooltip:e})}async setTitle(e){return l("plugin:tray|set_title",{rid:this.rid,title:e})}async setVisible(e){return l("plugin:tray|set_visible",{rid:this.rid,visible:e})}async setTempDirPath(e){return l("plugin:tray|set_temp_dir_path",{rid:this.rid,path:e})}async setIconAsTemplate(e){return l("plugin:tray|set_icon_as_template",{rid:this.rid,asTemplate:e})}async setMenuOnLeftClick(e){return l("plugin:tray|set_show_menu_on_left_click",{rid:this.rid,onLeft:e})}}var M,U,B,V=Object.freeze({__proto__:null,TrayIcon:O});function H(e){if("items"in e)e.items=e.items?.map((e=>"rid"in e?e:H(e)));else if("action"in e&&e.action){const n=new a;return n.onmessage=e.action,delete e.action,{...e,handler:n}}return e}async function G(e,n){const t=new a;let i=null;return n&&"object"==typeof n&&("action"in n&&n.action&&(t.onmessage=n.action,delete n.action),"items"in n&&n.items&&(i=n.items.map((e=>"rid"in e?[e.rid,e.kind]:H(e))))),l("plugin:menu|new",{kind:e,options:n?{...n,items:i}:void 0,handler:t})}class j extends N{get id(){return n(this,M,"f")}get kind(){return n(this,U,"f")}constructor(e,n,i){super(e),M.set(this,void 0),U.set(this,void 0),t(this,M,n,"f"),t(this,U,i,"f")}}M=new WeakMap,U=new WeakMap;class q extends j{constructor(e,n){super(e,n,"MenuItem")}static async new(e){return G("MenuItem",e).then((([e,n])=>new q(e,n)))}async text(){return l("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return l("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return l("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return l("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return l("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}}class Q extends j{constructor(e,n){super(e,n,"Check")}static async new(e){return G("Check",e).then((([e,n])=>new Q(e,n)))}async text(){return l("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return l("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return l("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return l("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return l("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}async isChecked(){return l("plugin:menu|is_checked",{rid:this.rid})}async setChecked(e){return l("plugin:menu|set_checked",{rid:this.rid,checked:e})}}!function(e){e.Add="Add",e.Advanced="Advanced",e.Bluetooth="Bluetooth",e.Bookmarks="Bookmarks",e.Caution="Caution",e.ColorPanel="ColorPanel",e.ColumnView="ColumnView",e.Computer="Computer",e.EnterFullScreen="EnterFullScreen",e.Everyone="Everyone",e.ExitFullScreen="ExitFullScreen",e.FlowView="FlowView",e.Folder="Folder",e.FolderBurnable="FolderBurnable",e.FolderSmart="FolderSmart",e.FollowLinkFreestanding="FollowLinkFreestanding",e.FontPanel="FontPanel",e.GoLeft="GoLeft",e.GoRight="GoRight",e.Home="Home",e.IChatTheater="IChatTheater",e.IconView="IconView",e.Info="Info",e.InvalidDataFreestanding="InvalidDataFreestanding",e.LeftFacingTriangle="LeftFacingTriangle",e.ListView="ListView",e.LockLocked="LockLocked",e.LockUnlocked="LockUnlocked",e.MenuMixedState="MenuMixedState",e.MenuOnState="MenuOnState",e.MobileMe="MobileMe",e.MultipleDocuments="MultipleDocuments",e.Network="Network",e.Path="Path",e.PreferencesGeneral="PreferencesGeneral",e.QuickLook="QuickLook",e.RefreshFreestanding="RefreshFreestanding",e.Refresh="Refresh",e.Remove="Remove",e.RevealFreestanding="RevealFreestanding",e.RightFacingTriangle="RightFacingTriangle",e.Share="Share",e.Slideshow="Slideshow",e.SmartBadge="SmartBadge",e.StatusAvailable="StatusAvailable",e.StatusNone="StatusNone",e.StatusPartiallyAvailable="StatusPartiallyAvailable",e.StatusUnavailable="StatusUnavailable",e.StopProgressFreestanding="StopProgressFreestanding",e.StopProgress="StopProgress",e.TrashEmpty="TrashEmpty",e.TrashFull="TrashFull",e.User="User",e.UserAccounts="UserAccounts",e.UserGroup="UserGroup",e.UserGuest="UserGuest"}(B||(B={}));class $ extends j{constructor(e,n){super(e,n,"Icon")}static async new(e){return G("Icon",e).then((([e,n])=>new $(e,n)))}async text(){return l("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return l("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return l("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return l("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return l("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}async setIcon(e){return l("plugin:menu|set_icon",{rid:this.rid,icon:e})}}class Z extends j{constructor(e,n){super(e,n,"Predefined")}static async new(e){return G("Predefined",e).then((([e,n])=>new Z(e,n)))}async text(){return l("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return l("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}}function J([e,n,t]){switch(t){case"Submenu":return new K(e,n);case"Predefined":return new Z(e,n);case"Check":return new Q(e,n);case"Icon":return new $(e,n);default:return new q(e,n)}}class K extends j{constructor(e,n){super(e,n,"Submenu")}static async new(e){return G("Submenu",e).then((([e,n])=>new K(e,n)))}async text(){return l("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return l("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return l("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return l("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async append(e){return l("plugin:menu|append",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async prepend(e){return l("plugin:menu|prepend",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async insert(e,n){return l("plugin:menu|insert",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e)),position:n})}async remove(e){return l("plugin:menu|remove",{rid:this.rid,kind:this.kind,item:[e.rid,e.kind]})}async removeAt(e){return l("plugin:menu|remove_at",{rid:this.rid,kind:this.kind,position:e}).then(J)}async items(){return l("plugin:menu|items",{rid:this.rid,kind:this.kind}).then((e=>e.map(J)))}async get(e){return l("plugin:menu|get",{rid:this.rid,kind:this.kind,id:e}).then((e=>e?J(e):null))}async popup(e,n){let t=null;return e&&(t={type:e instanceof b?"Physical":"Logical",data:e}),l("plugin:menu|popup",{rid:this.rid,kind:this.kind,window:n?.label??null,at:t})}async setAsWindowsMenuForNSApp(){return l("plugin:menu|set_as_windows_menu_for_nsapp",{rid:this.rid})}async setAsHelpMenuForNSApp(){return l("plugin:menu|set_as_help_menu_for_nsapp",{rid:this.rid})}}function Y([e,n,t]){switch(t){case"Submenu":return new K(e,n);case"Predefined":return new Z(e,n);case"Check":return new Q(e,n);case"Icon":return new $(e,n);default:return new q(e,n)}}class X extends j{constructor(e,n){super(e,n,"Menu")}static async new(e){return G("Menu",e).then((([e,n])=>new X(e,n)))}static async default(){return l("plugin:menu|default").then((([e,n])=>new X(e,n)))}async append(e){return l("plugin:menu|append",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async prepend(e){return l("plugin:menu|prepend",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e))})}async insert(e,n){return l("plugin:menu|insert",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map((e=>"rid"in e?[e.rid,e.kind]:e)),position:n})}async remove(e){return l("plugin:menu|remove",{rid:this.rid,kind:this.kind,item:[e.rid,e.kind]})}async removeAt(e){return l("plugin:menu|remove_at",{rid:this.rid,kind:this.kind,position:e}).then(Y)}async items(){return l("plugin:menu|items",{rid:this.rid,kind:this.kind}).then((e=>e.map(Y)))}async get(e){return l("plugin:menu|get",{rid:this.rid,kind:this.kind,id:e}).then((e=>e?Y(e):null))}async popup(e,n){let t=null;return e&&(t={type:e instanceof b?"Physical":"Logical",data:e}),l("plugin:menu|popup",{rid:this.rid,kind:this.kind,window:n?.label??null,at:t})}async setAsAppMenu(){return l("plugin:menu|set_as_app_menu",{rid:this.rid}).then((e=>e?new X(e[0],e[1]):null))}async setAsWindowMenu(e){return l("plugin:menu|set_as_window_menu",{rid:this.rid,window:e?.label??null}).then((e=>e?new X(e[0],e[1]):null))}}var ee=Object.freeze({__proto__:null,CheckMenuItem:Q,IconMenuItem:$,Menu:X,MenuItem:q,get NativeIcon(){return B},PredefinedMenuItem:Z,Submenu:K});return e.app=c,e.dpi=k,e.event=g,e.menu=ee,e.path=W,e.primitives=o,e.tray=V,e.window=z,e}({});window.__TAURI__=__TAURI_IIFE__; diff --git a/core/tauri/src/app.rs b/core/tauri/src/app.rs index 389858bff9a..364b9a41b3e 100644 --- a/core/tauri/src/app.rs +++ b/core/tauri/src/app.rs @@ -772,7 +772,8 @@ macro_rules! shared_app_impl { /// **You should always exit the tauri app immediately after this function returns and not use any tauri-related APIs.** pub fn cleanup_before_exit(&self) { #[cfg(all(desktop, feature = "tray-icon"))] - self.manager.tray.icons.lock().unwrap().clear() + self.manager.tray.icons.lock().unwrap().clear(); + self.manager.resources_table().clear(); } } }; @@ -787,6 +788,11 @@ impl App { self.handle.plugin(crate::event::plugin::init())?; self.handle.plugin(crate::window::plugin::init())?; self.handle.plugin(crate::app::plugin::init())?; + self.handle.plugin(crate::resources::plugin::init())?; + #[cfg(desktop)] + self.handle.plugin(crate::menu::plugin::init())?; + #[cfg(all(desktop, feature = "tray-icon"))] + self.handle.plugin(crate::tray::plugin::init())?; Ok(()) } diff --git a/core/tauri/src/error.rs b/core/tauri/src/error.rs index c8d8645dd48..9af98ec35f8 100644 --- a/core/tauri/src/error.rs +++ b/core/tauri/src/error.rs @@ -130,6 +130,12 @@ pub enum Error { /// window not found. #[error("window not found")] WindowNotFound, + /// The resource id is invalid. + #[error("The resource id {0} is invalid.")] + BadResourceId(crate::resources::ResourceId), + /// The anyhow crate error. + #[error(transparent)] + Anyhow(#[from] anyhow::Error), } /// `Result` diff --git a/core/tauri/src/ipc/channel.rs b/core/tauri/src/ipc/channel.rs index 92377071106..d650371961d 100644 --- a/core/tauri/src/ipc/channel.rs +++ b/core/tauri/src/ipc/channel.rs @@ -4,13 +4,14 @@ use std::{ collections::HashMap, + str::FromStr, sync::{ atomic::{AtomicU32, Ordering}, Arc, Mutex, }, }; -use serde::{Deserialize, Serialize, Serializer}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; use crate::{ command, @@ -50,6 +51,62 @@ impl Serialize for Channel { } } +/// The ID of a channel that was defined on the JavaScript layer. +/// +/// Useful when expecting [`Channel`] as part of a JSON object instead of a top-level command argument. +/// +/// # Examples +/// +/// ```rust +/// use tauri::{ipc::JavaScriptChannelId, Runtime, Window}; +/// +/// #[derive(serde::Deserialize)] +/// #[serde(rename_all = "camelCase")] +/// struct Button { +/// label: String, +/// on_click: JavaScriptChannelId, +/// } +/// +/// #[tauri::command] +/// fn add_button(window: Window, button: Button) { +/// let channel = button.on_click.channel_on(window); +/// channel.send("clicked").unwrap(); +/// } +/// ``` +pub struct JavaScriptChannelId(CallbackFn); + +impl FromStr for JavaScriptChannelId { + type Err = &'static str; + + fn from_str(s: &str) -> Result { + s.split_once(IPC_PAYLOAD_PREFIX) + .ok_or("invalid channel string") + .and_then(|(_prefix, id)| id.parse().map_err(|_| "invalid channel ID")) + .map(|id| Self(CallbackFn(id))) + } +} + +impl JavaScriptChannelId { + /// Gets a [`Channel`] for this channel ID on the given [`Window`]. + pub fn channel_on(&self, window: Window) -> Channel { + Channel::from_callback_fn(window, self.0) + } +} + +impl<'de> Deserialize<'de> for JavaScriptChannelId { + fn deserialize(deserializer: D) -> std::result::Result + where + D: Deserializer<'de>, + { + let value: String = Deserialize::deserialize(deserializer)?; + Self::from_str(&value).map_err(|_| { + serde::de::Error::custom(format!( + "invalid channel value `{value}`, expected a string in the `{IPC_PAYLOAD_PREFIX}ID` format" + )) + }) + } +} + impl Channel { /// Creates a new channel with the given message handler. pub fn new crate::Result<()> + Send + Sync + 'static>( @@ -58,7 +115,7 @@ impl Channel { Self::new_with_id(CHANNEL_COUNTER.fetch_add(1, Ordering::Relaxed), on_message) } - pub(crate) fn new_with_id crate::Result<()> + Send + Sync + 'static>( + fn new_with_id crate::Result<()> + Send + Sync + 'static>( id: u32, on_message: F, ) -> Self { @@ -74,7 +131,7 @@ impl Channel { channel } - pub(crate) fn from_ipc(window: Window, callback: CallbackFn) -> Self { + pub(crate) fn from_callback_fn(window: Window, callback: CallbackFn) -> Self { Channel::new_with_id(callback.0, move |body| { let data_id = CHANNEL_DATA_COUNTER.fetch_add(1, Ordering::Relaxed); window @@ -90,23 +147,12 @@ impl Channel { }) } - pub(crate) fn load_from_ipc( - window: Window, - value: impl AsRef, - ) -> Option { - value - .as_ref() - .split_once(IPC_PAYLOAD_PREFIX) - .and_then(|(_prefix, id)| id.parse().ok()) - .map(|callback_id| Self::from_ipc(window, CallbackFn(callback_id))) - } - /// The channel identifier. pub fn id(&self) -> u32 { self.id } - /// Sends the given data through the channel. + /// Sends the given data through the channel. pub fn send(&self, data: T) -> crate::Result<()> { let body = data.body()?; (self.on_message)(body) @@ -121,11 +167,13 @@ impl<'de, R: Runtime> CommandArg<'de, R> for Channel { let window = command.message.window(); let value: String = Deserialize::deserialize(command).map_err(|e| crate::Error::InvalidArgs(name, arg, e))?; - Channel::load_from_ipc(window, &value).ok_or_else(|| { - InvokeError::from_anyhow(anyhow::anyhow!( + JavaScriptChannelId::from_str(&value) + .map(|id| id.channel_on(window)) + .map_err(|_| { + InvokeError::from_anyhow(anyhow::anyhow!( "invalid channel value `{value}`, expected a string in the `{IPC_PAYLOAD_PREFIX}ID` format" )) - }) + }) } } diff --git a/core/tauri/src/ipc/mod.rs b/core/tauri/src/ipc/mod.rs index 02bf1f6a83c..eb37295f959 100644 --- a/core/tauri/src/ipc/mod.rs +++ b/core/tauri/src/ipc/mod.rs @@ -25,7 +25,7 @@ pub(crate) mod channel; pub(crate) mod format_callback; pub(crate) mod protocol; -pub use channel::Channel; +pub use channel::{Channel, JavaScriptChannelId}; /// A closure that is run every time Tauri receives a message it doesn't explicitly handle. pub type InvokeHandler = dyn Fn(Invoke) -> bool + Send + Sync + 'static; diff --git a/core/tauri/src/ipc/protocol.rs b/core/tauri/src/ipc/protocol.rs index 61bf68ee9b4..14e5780dec3 100644 --- a/core/tauri/src/ipc/protocol.rs +++ b/core/tauri/src/ipc/protocol.rs @@ -245,7 +245,7 @@ fn handle_ipc_message(message: String, manager: &AppManager, labe if !(cfg!(target_os = "macos") || cfg!(target_os = "ios")) && matches!(v, JsonValue::Object(_) | JsonValue::Array(_)) { - let _ = Channel::from_ipc(window, callback).send(v); + let _ = Channel::from_callback_fn(window, callback).send(v); } else { responder_eval( &window, @@ -262,7 +262,8 @@ fn handle_ipc_message(message: String, manager: &AppManager, labe error, ); } else { - let _ = Channel::from_ipc(window, callback).send(InvokeBody::Raw(v.clone())); + let _ = + Channel::from_callback_fn(window, callback).send(InvokeBody::Raw(v.clone())); } } InvokeResponse::Err(e) => responder_eval( diff --git a/core/tauri/src/lib.rs b/core/tauri/src/lib.rs index 61b3338aac1..7acc2595b6e 100644 --- a/core/tauri/src/lib.rs +++ b/core/tauri/src/lib.rs @@ -82,6 +82,7 @@ mod manager; mod pattern; pub mod plugin; pub(crate) mod protocol; +mod resources; mod vibrancy; pub mod window; use tauri_runtime as runtime; @@ -160,7 +161,7 @@ pub use tauri_runtime_wry::wry; /// A task to run on the main thread. pub type SyncTask = Box; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use std::{ collections::HashMap, fmt::{self, Debug}, @@ -903,6 +904,40 @@ mod tests { } } +#[derive(Deserialize)] +#[serde(untagged)] +pub(crate) enum IconDto { + #[cfg(any(feature = "icon-png", feature = "icon-ico"))] + File(std::path::PathBuf), + #[cfg(any(feature = "icon-png", feature = "icon-ico"))] + Raw(Vec), + Rgba { + rgba: Vec, + width: u32, + height: u32, + }, +} + +impl From for Icon { + fn from(icon: IconDto) -> Self { + match icon { + #[cfg(any(feature = "icon-png", feature = "icon-ico"))] + IconDto::File(path) => Self::File(path), + #[cfg(any(feature = "icon-png", feature = "icon-ico"))] + IconDto::Raw(raw) => Self::Raw(raw), + IconDto::Rgba { + rgba, + width, + height, + } => Self::Rgba { + rgba, + width, + height, + }, + } + } +} + #[allow(unused)] macro_rules! run_main_thread { ($self:ident, $ex:expr) => {{ diff --git a/core/tauri/src/manager/mod.rs b/core/tauri/src/manager/mod.rs index 92ed1b07249..a30fee40083 100644 --- a/core/tauri/src/manager/mod.rs +++ b/core/tauri/src/manager/mod.rs @@ -6,7 +6,7 @@ use std::{ borrow::Cow, collections::HashMap, fmt, - sync::{Arc, Mutex}, + sync::{Arc, Mutex, MutexGuard}, }; use serde::Serialize; @@ -20,7 +20,6 @@ use tauri_utils::{ html::{SCRIPT_NONCE_TOKEN, STYLE_NONCE_TOKEN}, }; -use crate::event::EmitArgs; use crate::{ app::{AppHandle, GlobalWindowEventListener, OnPageLoad}, event::{assert_event_name_is_valid, Event, EventId, Listeners}, @@ -33,6 +32,7 @@ use crate::{ }, Context, Pattern, Runtime, StateManager, Window, }; +use crate::{event::EmitArgs, resources::ResourceTable}; #[cfg(desktop)] mod menu; @@ -196,6 +196,9 @@ pub struct AppManager { /// Application pattern. pub pattern: Arc, + + /// Application Resources Table + pub(crate) resources_table: Arc>, } impl fmt::Debug for AppManager { @@ -274,6 +277,7 @@ impl AppManager { app_icon: context.app_icon, package_info: context.package_info, pattern: Arc::new(context.pattern), + resources_table: Arc::default(), } } @@ -535,6 +539,14 @@ impl AppManager { pub fn windows(&self) -> HashMap> { self.window.windows_lock().clone() } + + /// Resources table managed by the application. + pub(crate) fn resources_table(&self) -> MutexGuard<'_, ResourceTable> { + self + .resources_table + .lock() + .expect("poisoned window manager") + } } #[cfg(desktop)] diff --git a/core/tauri/src/menu/check.rs b/core/tauri/src/menu/check.rs index 28d90990f2e..97fa639601e 100644 --- a/core/tauri/src/menu/check.rs +++ b/core/tauri/src/menu/check.rs @@ -2,9 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use crate::{menu::MenuId, run_main_thread, AppHandle, Manager, Runtime}; +use crate::{menu::MenuId, resources::Resource, run_main_thread, AppHandle, Manager, Runtime}; -/// A menu item inside a [`Menu`] or [`Submenu`] and contains only text. +/// A menu item inside a [`Menu`] or [`Submenu`] +/// and usually contains a text and a check mark or a similar toggle +/// that corresponds to a checked and unchecked states. /// /// [`Menu`]: super::Menu /// [`Submenu`]: super::Submenu @@ -31,7 +33,7 @@ unsafe impl Sync for CheckMenuItem {} unsafe impl Send for CheckMenuItem {} impl super::sealed::IsMenuItemBase for CheckMenuItem { - fn inner(&self) -> &dyn muda::IsMenuItem { + fn inner_muda(&self) -> &dyn muda::IsMenuItem { &self.inner } } @@ -146,3 +148,5 @@ impl CheckMenuItem { run_main_thread!(self, |self_: Self| self_.inner.set_checked(checked)) } } + +impl Resource for CheckMenuItem {} diff --git a/core/tauri/src/menu/icon.rs b/core/tauri/src/menu/icon.rs index bdaab020386..e2dd547e095 100644 --- a/core/tauri/src/menu/icon.rs +++ b/core/tauri/src/menu/icon.rs @@ -3,9 +3,12 @@ // SPDX-License-Identifier: MIT use super::NativeIcon; -use crate::{menu::MenuId, run_main_thread, AppHandle, Icon, Manager, Runtime}; +use crate::{ + menu::MenuId, resources::Resource, run_main_thread, AppHandle, Icon, Manager, Runtime, +}; -/// A menu item inside a [`Menu`] or [`Submenu`] and contains only text. +/// A menu item inside a [`Menu`] or [`Submenu`] +/// and usually contains an icon and a text. /// /// [`Menu`]: super::Menu /// [`Submenu`]: super::Submenu @@ -32,7 +35,7 @@ unsafe impl Sync for IconMenuItem {} unsafe impl Send for IconMenuItem {} impl super::sealed::IsMenuItemBase for IconMenuItem { - fn inner(&self) -> &dyn muda::IsMenuItem { + fn inner_muda(&self) -> &dyn muda::IsMenuItem { &self.inner } } @@ -214,3 +217,5 @@ impl IconMenuItem { Ok(()) } } + +impl Resource for IconMenuItem {} diff --git a/core/tauri/src/menu/menu.rs b/core/tauri/src/menu/menu.rs index a29ecb3300d..12aae7dbfbc 100644 --- a/core/tauri/src/menu/menu.rs +++ b/core/tauri/src/menu/menu.rs @@ -4,6 +4,7 @@ use super::sealed::ContextMenuBase; use super::{AboutMetadata, IsMenuItem, MenuItemKind, PredefinedMenuItem, Submenu}; +use crate::resources::Resource; use crate::Window; use crate::{run_main_thread, AppHandle, Manager, Position, Runtime}; use muda::ContextMenu; @@ -84,12 +85,12 @@ impl ContextMenuBase for Menu { } }) } - fn inner(&self) -> &dyn muda::ContextMenu { + fn inner_context(&self) -> &dyn muda::ContextMenu { &self.inner } - fn inner_owned(&self) -> Box { - Box::new(self.clone().inner) + fn inner_context_owned(&self) -> Box { + Box::new(self.inner.clone()) } } @@ -261,8 +262,10 @@ impl Menu { /// [`Submenu`]: super::Submenu pub fn append(&self, item: &dyn IsMenuItem) -> crate::Result<()> { let kind = item.kind(); - run_main_thread!(self, |self_: Self| self_.inner.append(kind.inner().inner()))? - .map_err(Into::into) + run_main_thread!(self, |self_: Self| self_ + .inner + .append(kind.inner().inner_muda()))? + .map_err(Into::into) } /// Add menu items to the end of this menu. It calls [`Menu::append`] in a loop internally. @@ -291,7 +294,7 @@ impl Menu { let kind = item.kind(); run_main_thread!(self, |self_: Self| self_ .inner - .prepend(kind.inner().inner()))? + .prepend(kind.inner().inner_muda()))? .map_err(Into::into) } @@ -317,7 +320,7 @@ impl Menu { let kind = item.kind(); run_main_thread!(self, |self_: Self| self_ .inner - .insert(kind.inner().inner(), position))? + .insert(kind.inner().inner_muda(), position))? .map_err(Into::into) } @@ -339,8 +342,18 @@ impl Menu { /// Remove a menu item from this menu. pub fn remove(&self, item: &dyn IsMenuItem) -> crate::Result<()> { let kind = item.kind(); - run_main_thread!(self, |self_: Self| self_.inner.remove(kind.inner().inner()))? - .map_err(Into::into) + run_main_thread!(self, |self_: Self| self_ + .inner + .remove(kind.inner().inner_muda()))? + .map_err(Into::into) + } + + /// Remove the menu item at the specified position from this menu and returns it. + pub fn remove_at(&self, position: usize) -> crate::Result>> { + run_main_thread!(self, |self_: Self| self_ + .inner + .remove_at(position) + .map(|i| MenuItemKind::from_muda(self_.app_handle.clone(), i))) } /// Retrieves the menu item matching the given identifier. @@ -358,40 +371,27 @@ impl Menu { /// Returns a list of menu items that has been added to this menu. pub fn items(&self) -> crate::Result>> { - let handle = self.app_handle.clone(); run_main_thread!(self, |self_: Self| self_ .inner .items() .into_iter() - .map(|i| match i { - muda::MenuItemKind::MenuItem(i) => super::MenuItemKind::MenuItem(super::MenuItem { - id: i.id().clone(), - inner: i, - app_handle: handle.clone(), - }), - muda::MenuItemKind::Submenu(i) => super::MenuItemKind::Submenu(super::Submenu { - id: i.id().clone(), - inner: i, - app_handle: handle.clone(), - }), - muda::MenuItemKind::Predefined(i) => { - super::MenuItemKind::Predefined(super::PredefinedMenuItem { - id: i.id().clone(), - inner: i, - app_handle: handle.clone(), - }) - } - muda::MenuItemKind::Check(i) => super::MenuItemKind::Check(super::CheckMenuItem { - id: i.id().clone(), - inner: i, - app_handle: handle.clone(), - }), - muda::MenuItemKind::Icon(i) => super::MenuItemKind::Icon(super::IconMenuItem { - id: i.id().clone(), - inner: i, - app_handle: handle.clone(), - }), - }) + .map(|i| MenuItemKind::from_muda(self_.app_handle.clone(), i)) .collect::>()) } + + /// Set this menu as the application menu. + /// + /// This is an alias for [`AppHandle::set_menu`]. + pub fn set_as_app_menu(&self) -> crate::Result>> { + self.app_handle.set_menu(self.clone()) + } + + /// Set this menu as the window menu. + /// + /// This is an alias for [`Window::set_menu`]. + pub fn set_as_window_menu(&self, window: &Window) -> crate::Result>> { + window.set_menu(self.clone()) + } } + +impl Resource for Menu {} diff --git a/core/tauri/src/menu/mod.rs b/core/tauri/src/menu/mod.rs index eaba4b52e73..53488caf165 100644 --- a/core/tauri/src/menu/mod.rs +++ b/core/tauri/src/menu/mod.rs @@ -4,7 +4,7 @@ #![cfg(desktop)] -//! Menu types and utility functions +//! Menu types and utilities. // TODO(muda-migration): figure out js events @@ -14,6 +14,7 @@ mod icon; #[allow(clippy::module_inception)] mod menu; mod normal; +pub(crate) mod plugin; mod predefined; mod submenu; pub use builders::*; @@ -22,13 +23,14 @@ pub use icon::IconMenuItem; pub use menu::{Menu, HELP_SUBMENU_ID, WINDOW_SUBMENU_ID}; pub use normal::MenuItem; pub use predefined::PredefinedMenuItem; +use serde::{Deserialize, Serialize}; pub use submenu::Submenu; -use crate::{Icon, Runtime}; +use crate::{AppHandle, Icon, Runtime}; pub use muda::MenuId; /// Describes a menu event emitted when a menu item is activated -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Serialize)] pub struct MenuEvent { /// Id of the menu item which triggered this event pub id: MenuId, @@ -233,7 +235,7 @@ impl From for muda::AboutMetadata { /// ## Platform-specific: /// /// - **Windows / Linux**: Unsupported. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)] pub enum NativeIcon { /// An add item template image. Add, @@ -449,6 +451,36 @@ impl MenuItemKind { } } + pub(crate) fn from_muda(app_handle: AppHandle, i: muda::MenuItemKind) -> Self { + match i { + muda::MenuItemKind::MenuItem(i) => Self::MenuItem(MenuItem { + id: i.id().clone(), + inner: i, + app_handle, + }), + muda::MenuItemKind::Submenu(i) => Self::Submenu(Submenu { + id: i.id().clone(), + inner: i, + app_handle, + }), + muda::MenuItemKind::Predefined(i) => Self::Predefined(PredefinedMenuItem { + id: i.id().clone(), + inner: i, + app_handle, + }), + muda::MenuItemKind::Check(i) => Self::Check(CheckMenuItem { + id: i.id().clone(), + inner: i, + app_handle, + }), + muda::MenuItemKind::Icon(i) => Self::Icon(IconMenuItem { + id: i.id().clone(), + inner: i, + app_handle, + }), + } + } + /// Casts this item to a [`MenuItem`], and returns `None` if it wasn't. pub fn as_menuitem(&self) -> Option<&MenuItem> { match self { @@ -543,8 +575,8 @@ impl Clone for MenuItemKind { } impl sealed::IsMenuItemBase for MenuItemKind { - fn inner(&self) -> &dyn muda::IsMenuItem { - self.inner().inner() + fn inner_muda(&self) -> &dyn muda::IsMenuItem { + self.inner().inner_muda() } } @@ -593,12 +625,12 @@ pub trait ContextMenu: sealed::ContextMenuBase + Send + Sync { pub(crate) mod sealed { pub trait IsMenuItemBase { - fn inner(&self) -> &dyn muda::IsMenuItem; + fn inner_muda(&self) -> &dyn muda::IsMenuItem; } pub trait ContextMenuBase { - fn inner(&self) -> &dyn muda::ContextMenu; - fn inner_owned(&self) -> Box; + fn inner_context(&self) -> &dyn muda::ContextMenu; + fn inner_context_owned(&self) -> Box; fn popup_inner>( &self, window: crate::Window, diff --git a/core/tauri/src/menu/normal.rs b/core/tauri/src/menu/normal.rs index a7eeb3e6b71..cd1f64bca0a 100644 --- a/core/tauri/src/menu/normal.rs +++ b/core/tauri/src/menu/normal.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use crate::{menu::MenuId, run_main_thread, AppHandle, Manager, Runtime}; +use crate::{menu::MenuId, resources::Resource, run_main_thread, AppHandle, Manager, Runtime}; /// A menu item inside a [`Menu`] or [`Submenu`] and contains only text. /// @@ -31,7 +31,7 @@ unsafe impl Sync for MenuItem {} unsafe impl Send for MenuItem {} impl super::sealed::IsMenuItemBase for MenuItem { - fn inner(&self) -> &dyn muda::IsMenuItem { + fn inner_muda(&self) -> &dyn muda::IsMenuItem { &self.inner } } @@ -132,3 +132,5 @@ impl MenuItem { run_main_thread!(self, |self_: Self| self_.inner.set_accelerator(accel))?.map_err(Into::into) } } + +impl Resource for MenuItem {} diff --git a/core/tauri/src/menu/plugin.rs b/core/tauri/src/menu/plugin.rs new file mode 100644 index 00000000000..c659bf349f4 --- /dev/null +++ b/core/tauri/src/menu/plugin.rs @@ -0,0 +1,876 @@ +// Copyright 2019-2023 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use std::{ + collections::HashMap, + sync::{Mutex, MutexGuard}, +}; + +use serde::{Deserialize, Serialize}; +use tauri_runtime::window::dpi::Position; + +use super::{sealed::ContextMenuBase, *}; +use crate::{ + command, + ipc::{channel::JavaScriptChannelId, Channel}, + plugin::{Builder, TauriPlugin}, + resources::{ResourceId, ResourceTable}, + AppHandle, IconDto, Manager, RunEvent, Runtime, State, Window, +}; +use tauri_macros::do_menu_item; + +#[derive(Deserialize, Serialize)] +pub(crate) enum ItemKind { + Menu, + MenuItem, + Predefined, + Submenu, + Check, + Icon, +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct AboutMetadata { + pub name: Option, + pub version: Option, + pub short_version: Option, + pub authors: Option>, + pub comments: Option, + pub copyright: Option, + pub license: Option, + pub website: Option, + pub website_label: Option, + pub credits: Option, + pub icon: Option, +} + +impl From for super::AboutMetadata { + fn from(value: AboutMetadata) -> Self { + Self { + name: value.name, + version: value.version, + short_version: value.short_version, + authors: value.authors, + comments: value.comments, + copyright: value.copyright, + license: value.license, + website: value.website, + website_label: value.website_label, + credits: value.credits, + icon: value.icon.map(Into::into), + } + } +} + +#[allow(clippy::large_enum_variant)] +#[derive(Deserialize)] +enum Predefined { + Separator, + Copy, + Cut, + Paste, + SelectAll, + Undo, + Redo, + Minimize, + Maximize, + Fullscreen, + Hide, + HideOthers, + ShowAll, + CloseWindow, + Quit, + About(Option), + Services, +} + +#[derive(Deserialize)] +struct SubmenuPayload { + id: Option, + text: String, + enabled: Option, + items: Vec, +} + +impl SubmenuPayload { + pub fn create_item( + self, + window: &Window, + resources_table: &MutexGuard<'_, ResourceTable>, + ) -> crate::Result> { + let mut builder = if let Some(id) = self.id { + SubmenuBuilder::with_id(window, id, self.text) + } else { + SubmenuBuilder::new(window, self.text) + }; + if let Some(enabled) = self.enabled { + builder = builder.enabled(enabled); + } + for item in self.items { + builder = item.with_item(window, resources_table, |i| Ok(builder.item(i)))?; + } + + builder.build() + } +} + +#[derive(Deserialize)] +struct CheckMenuItemPayload { + handler: Option, + id: Option, + text: String, + checked: bool, + enabled: Option, + accelerator: Option, +} + +impl CheckMenuItemPayload { + pub fn create_item(self, window: &Window) -> CheckMenuItem { + let mut builder = if let Some(id) = self.id { + CheckMenuItemBuilder::with_id(id, self.text) + } else { + CheckMenuItemBuilder::new(self.text) + }; + if let Some(accelerator) = self.accelerator { + builder = builder.accelerator(accelerator); + } + if let Some(enabled) = self.enabled { + builder = builder.enabled(enabled); + } + + let item = builder.checked(self.checked).build(window); + + if let Some(handler) = self.handler { + let handler = handler.channel_on(window.clone()); + window + .state::() + .0 + .lock() + .unwrap() + .insert(item.id().clone(), handler); + } + + item + } +} + +#[derive(Deserialize)] +#[serde(untagged)] +enum Icon { + Native(NativeIcon), + Icon(IconDto), +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct IconMenuItemPayload { + handler: Option, + id: Option, + text: String, + icon: Icon, + enabled: Option, + accelerator: Option, +} + +impl IconMenuItemPayload { + pub fn create_item(self, window: &Window) -> IconMenuItem { + let mut builder = if let Some(id) = self.id { + IconMenuItemBuilder::with_id(id, self.text) + } else { + IconMenuItemBuilder::new(self.text) + }; + if let Some(accelerator) = self.accelerator { + builder = builder.accelerator(accelerator); + } + if let Some(enabled) = self.enabled { + builder = builder.enabled(enabled); + } + builder = match self.icon { + Icon::Native(native_icon) => builder.native_icon(native_icon), + Icon::Icon(icon) => builder.icon(icon.into()), + }; + + let item = builder.build(window); + + if let Some(handler) = self.handler { + let handler = handler.channel_on(window.clone()); + window + .state::() + .0 + .lock() + .unwrap() + .insert(item.id().clone(), handler); + } + + item + } +} + +#[derive(Deserialize)] +struct MenuItemPayload { + handler: Option, + id: Option, + text: String, + enabled: Option, + accelerator: Option, +} + +impl MenuItemPayload { + pub fn create_item(self, window: &Window) -> MenuItem { + let mut builder = if let Some(id) = self.id { + MenuItemBuilder::with_id(id, self.text) + } else { + MenuItemBuilder::new(self.text) + }; + if let Some(accelerator) = self.accelerator { + builder = builder.accelerator(accelerator); + } + if let Some(enabled) = self.enabled { + builder = builder.enabled(enabled); + } + + let item = builder.build(window); + + if let Some(handler) = self.handler { + let handler = handler.channel_on(window.clone()); + window + .state::() + .0 + .lock() + .unwrap() + .insert(item.id().clone(), handler); + } + + item + } +} + +#[derive(Deserialize)] +struct PredefinedMenuItemPayload { + item: Predefined, + text: Option, +} + +impl PredefinedMenuItemPayload { + pub fn create_item(self, window: &Window) -> PredefinedMenuItem { + match self.item { + Predefined::Separator => PredefinedMenuItem::separator(window), + Predefined::Copy => PredefinedMenuItem::copy(window, self.text.as_deref()), + Predefined::Cut => PredefinedMenuItem::cut(window, self.text.as_deref()), + Predefined::Paste => PredefinedMenuItem::paste(window, self.text.as_deref()), + Predefined::SelectAll => PredefinedMenuItem::select_all(window, self.text.as_deref()), + Predefined::Undo => PredefinedMenuItem::undo(window, self.text.as_deref()), + Predefined::Redo => PredefinedMenuItem::redo(window, self.text.as_deref()), + Predefined::Minimize => PredefinedMenuItem::minimize(window, self.text.as_deref()), + Predefined::Maximize => PredefinedMenuItem::maximize(window, self.text.as_deref()), + Predefined::Fullscreen => PredefinedMenuItem::fullscreen(window, self.text.as_deref()), + Predefined::Hide => PredefinedMenuItem::hide(window, self.text.as_deref()), + Predefined::HideOthers => PredefinedMenuItem::hide_others(window, self.text.as_deref()), + Predefined::ShowAll => PredefinedMenuItem::show_all(window, self.text.as_deref()), + Predefined::CloseWindow => PredefinedMenuItem::close_window(window, self.text.as_deref()), + Predefined::Quit => PredefinedMenuItem::quit(window, self.text.as_deref()), + Predefined::About(metadata) => { + PredefinedMenuItem::about(window, self.text.as_deref(), metadata.map(Into::into)) + } + Predefined::Services => PredefinedMenuItem::services(window, self.text.as_deref()), + } + } +} + +#[derive(Deserialize)] +#[serde(untagged)] +enum MenuItemPayloadKind { + ExistingItem((ResourceId, ItemKind)), + Predefined(PredefinedMenuItemPayload), + Check(CheckMenuItemPayload), + Submenu(SubmenuPayload), + Icon(IconMenuItemPayload), + MenuItem(MenuItemPayload), +} + +impl MenuItemPayloadKind { + pub fn with_item) -> crate::Result>( + self, + window: &Window, + resources_table: &MutexGuard<'_, ResourceTable>, + f: F, + ) -> crate::Result { + match self { + Self::ExistingItem((rid, kind)) => { + do_menu_item!(resources_table, rid, kind, |i| f(&*i)) + } + Self::Submenu(i) => f(&i.create_item(window, resources_table)?), + Self::Predefined(i) => f(&i.create_item(window)), + Self::Check(i) => f(&i.create_item(window)), + Self::Icon(i) => f(&i.create_item(window)), + Self::MenuItem(i) => f(&i.create_item(window)), + } + } +} + +#[derive(Deserialize, Default)] +#[serde(rename_all = "camelCase")] +struct NewOptions { + id: Option, + text: Option, + enabled: Option, + checked: Option, + accelerator: Option, + #[serde(rename = "item")] + predefined_item: Option, + icon: Option, + items: Option>, +} + +#[command(root = "crate")] +fn new( + app: AppHandle, + window: Window, + kind: ItemKind, + options: Option, + channels: State<'_, MenuChannels>, + handler: Channel, +) -> crate::Result<(ResourceId, MenuId)> { + let options = options.unwrap_or_default(); + let mut resources_table = app.manager.resources_table(); + + let (rid, id) = match kind { + ItemKind::Menu => { + let mut builder = MenuBuilder::new(&app); + if let Some(id) = options.id { + builder = builder.id(id); + } + if let Some(items) = options.items { + for item in items { + builder = item.with_item(&window, &resources_table, |i| Ok(builder.item(i)))?; + } + } + let menu = builder.build()?; + let id = menu.id().clone(); + let rid = resources_table.add(menu); + + (rid, id) + } + + ItemKind::Submenu => { + let submenu = SubmenuPayload { + id: options.id, + text: options.text.unwrap_or_default(), + enabled: options.enabled, + items: options.items.unwrap_or_default(), + } + .create_item(&window, &resources_table)?; + let id = submenu.id().clone(); + let rid = resources_table.add(submenu); + + (rid, id) + } + + ItemKind::MenuItem => { + let item = MenuItemPayload { + // handler managed in this function instead + handler: None, + id: options.id, + text: options.text.unwrap_or_default(), + enabled: options.enabled, + accelerator: options.accelerator, + } + .create_item(&window); + let id = item.id().clone(); + let rid = resources_table.add(item); + (rid, id) + } + + ItemKind::Predefined => { + let item = PredefinedMenuItemPayload { + item: options.predefined_item.unwrap(), + text: options.text, + } + .create_item(&window); + let id = item.id().clone(); + let rid = resources_table.add(item); + (rid, id) + } + + ItemKind::Check => { + let item = CheckMenuItemPayload { + // handler managed in this function instead + handler: None, + id: options.id, + text: options.text.unwrap_or_default(), + checked: options.checked.unwrap_or_default(), + enabled: options.enabled, + accelerator: options.accelerator, + } + .create_item(&window); + let id = item.id().clone(); + let rid = resources_table.add(item); + (rid, id) + } + + ItemKind::Icon => { + let item = IconMenuItemPayload { + // handler managed in this function instead + handler: None, + id: options.id, + text: options.text.unwrap_or_default(), + icon: options.icon.unwrap_or(Icon::Native(NativeIcon::User)), + enabled: options.enabled, + accelerator: options.accelerator, + } + .create_item(&window); + let id = item.id().clone(); + let rid = resources_table.add(item); + (rid, id) + } + }; + + channels.0.lock().unwrap().insert(id.clone(), handler); + + Ok((rid, id)) +} + +#[command(root = "crate")] +fn append( + window: Window, + rid: ResourceId, + kind: ItemKind, + items: Vec, +) -> crate::Result<()> { + let resources_table = window.manager.resources_table(); + match kind { + ItemKind::Menu => { + let menu = resources_table.get::>(rid)?; + for item in items { + item.with_item(&window, &resources_table, |i| menu.append(i))?; + } + } + ItemKind::Submenu => { + let submenu = resources_table.get::>(rid)?; + for item in items { + item.with_item(&window, &resources_table, |i| submenu.append(i))?; + } + } + _ => return Err(anyhow::anyhow!("unexpected menu item kind").into()), + }; + + Ok(()) +} + +#[command(root = "crate")] +fn prepend( + window: Window, + rid: ResourceId, + kind: ItemKind, + items: Vec, +) -> crate::Result<()> { + let resources_table = window.manager.resources_table(); + match kind { + ItemKind::Menu => { + let menu = resources_table.get::>(rid)?; + for item in items { + item.with_item(&window, &resources_table, |i| menu.prepend(i))?; + } + } + ItemKind::Submenu => { + let submenu = resources_table.get::>(rid)?; + for item in items { + item.with_item(&window, &resources_table, |i| submenu.prepend(i))?; + } + } + _ => return Err(anyhow::anyhow!("unexpected menu item kind").into()), + }; + + Ok(()) +} + +#[command(root = "crate")] +fn insert( + window: Window, + rid: ResourceId, + kind: ItemKind, + items: Vec, + mut position: usize, +) -> crate::Result<()> { + let resources_table = window.manager.resources_table(); + match kind { + ItemKind::Menu => { + let menu = resources_table.get::>(rid)?; + for item in items { + item.with_item(&window, &resources_table, |i| menu.insert(i, position))?; + position += 1 + } + } + ItemKind::Submenu => { + let submenu = resources_table.get::>(rid)?; + for item in items { + item.with_item(&window, &resources_table, |i| submenu.insert(i, position))?; + position += 1 + } + } + _ => return Err(anyhow::anyhow!("unexpected menu item kind").into()), + }; + + Ok(()) +} + +#[command(root = "crate")] +fn remove( + app: AppHandle, + menu_rid: ResourceId, + menu_kind: ItemKind, + item: (ResourceId, ItemKind), +) -> crate::Result<()> { + let resources_table = app.manager.resources_table(); + let (rid, kind) = item; + match menu_kind { + ItemKind::Menu => { + let menu = resources_table.get::>(menu_rid)?; + do_menu_item!(resources_table, rid, kind, |i| menu.remove(&*i))?; + } + ItemKind::Submenu => { + let submenu = resources_table.get::>(menu_rid)?; + do_menu_item!(resources_table, rid, kind, |i| submenu.remove(&*i))?; + } + _ => return Err(anyhow::anyhow!("unexpected menu item kind").into()), + }; + + Ok(()) +} + +macro_rules! make_item_resource { + ($resources_table:ident, $item:ident) => {{ + let id = $item.id().clone(); + let (rid, kind) = match $item { + MenuItemKind::MenuItem(i) => ($resources_table.add(i), ItemKind::MenuItem), + MenuItemKind::Submenu(i) => ($resources_table.add(i), ItemKind::Submenu), + MenuItemKind::Predefined(i) => ($resources_table.add(i), ItemKind::Predefined), + MenuItemKind::Check(i) => ($resources_table.add(i), ItemKind::Check), + MenuItemKind::Icon(i) => ($resources_table.add(i), ItemKind::Icon), + }; + (rid, id, kind) + }}; +} + +#[command(root = "crate")] +fn remove_at( + app: AppHandle, + rid: ResourceId, + kind: ItemKind, + position: usize, +) -> crate::Result> { + let mut resources_table = app.manager.resources_table(); + match kind { + ItemKind::Menu => { + let menu = resources_table.get::>(rid)?; + if let Some(item) = menu.remove_at(position)? { + return Ok(Some(make_item_resource!(resources_table, item))); + } + } + ItemKind::Submenu => { + let submenu = resources_table.get::>(rid)?; + if let Some(item) = submenu.remove_at(position)? { + return Ok(Some(make_item_resource!(resources_table, item))); + } + } + _ => return Err(anyhow::anyhow!("unexpected menu item kind").into()), + }; + + Ok(None) +} + +#[command(root = "crate")] +fn items( + app: AppHandle, + rid: ResourceId, + kind: ItemKind, +) -> crate::Result> { + let mut resources_table = app.manager.resources_table(); + let items = match kind { + ItemKind::Menu => resources_table.get::>(rid)?.items()?, + ItemKind::Submenu => resources_table.get::>(rid)?.items()?, + _ => return Err(anyhow::anyhow!("unexpected menu item kind").into()), + }; + + Ok( + items + .into_iter() + .map(|i| make_item_resource!(resources_table, i)) + .collect::>(), + ) +} + +#[command(root = "crate")] +fn get( + app: AppHandle, + rid: ResourceId, + kind: ItemKind, + id: MenuId, +) -> crate::Result> { + let mut resources_table = app.manager.resources_table(); + match kind { + ItemKind::Menu => { + let menu = resources_table.get::>(rid)?; + if let Some(item) = menu.get(&id) { + return Ok(Some(make_item_resource!(resources_table, item))); + } + } + ItemKind::Submenu => { + let submenu = resources_table.get::>(rid)?; + if let Some(item) = submenu.get(&id) { + return Ok(Some(make_item_resource!(resources_table, item))); + } + } + _ => return Err(anyhow::anyhow!("unexpected menu item kind").into()), + }; + + Ok(None) +} + +#[command(root = "crate")] +async fn popup( + app: AppHandle, + current_window: Window, + rid: ResourceId, + kind: ItemKind, + window: Option, + at: Option, +) -> crate::Result<()> { + let window = window + .map(|w| app.get_window(&w)) + .unwrap_or(Some(current_window)); + + if let Some(window) = window { + let resources_table = app.manager.resources_table(); + match kind { + ItemKind::Menu => { + let menu = resources_table.get::>(rid)?; + menu.popup_inner(window, at)?; + } + ItemKind::Submenu => { + let submenu = resources_table.get::>(rid)?; + submenu.popup_inner(window, at)?; + } + _ => return Err(anyhow::anyhow!("unexpected menu item kind").into()), + }; + } + + Ok(()) +} + +#[command(root = "crate")] +fn default(app: AppHandle) -> crate::Result<(ResourceId, MenuId)> { + let mut resources_table = app.manager.resources_table(); + let menu = Menu::default(&app)?; + let id = menu.id().clone(); + let rid = resources_table.add(menu); + Ok((rid, id)) +} + +#[command(root = "crate")] +async fn set_as_app_menu( + app: AppHandle, + rid: ResourceId, +) -> crate::Result> { + let mut resources_table = app.manager.resources_table(); + let menu = resources_table.get::>(rid)?; + if let Some(menu) = menu.set_as_app_menu()? { + let id = menu.id().clone(); + let rid = resources_table.add(menu); + return Ok(Some((rid, id))); + } + Ok(None) +} + +#[command(root = "crate")] +async fn set_as_window_menu( + app: AppHandle, + current_window: Window, + rid: ResourceId, + window: Option, +) -> crate::Result> { + let window = window + .map(|w| app.get_window(&w)) + .unwrap_or(Some(current_window)); + + if let Some(window) = window { + let mut resources_table = app.manager.resources_table(); + let menu = resources_table.get::>(rid)?; + if let Some(menu) = menu.set_as_window_menu(&window)? { + let id = menu.id().clone(); + let rid = resources_table.add(menu); + return Ok(Some((rid, id))); + } + } + Ok(None) +} + +#[command(root = "crate")] +fn text(app: AppHandle, rid: ResourceId, kind: ItemKind) -> crate::Result { + let resources_table = app.manager.resources_table(); + do_menu_item!(resources_table, rid, kind, |i| i.text()) +} + +#[command(root = "crate")] +fn set_text( + app: AppHandle, + rid: ResourceId, + kind: ItemKind, + text: String, +) -> crate::Result<()> { + let resources_table = app.manager.resources_table(); + do_menu_item!(resources_table, rid, kind, |i| i.set_text(text)) +} + +#[command(root = "crate")] +fn is_enabled( + app: AppHandle, + rid: ResourceId, + kind: ItemKind, +) -> crate::Result { + let resources_table = app.manager.resources_table(); + do_menu_item!(resources_table, rid, kind, |i| i.is_enabled(), !Predefined) +} + +#[command(root = "crate")] +fn set_enabled( + app: AppHandle, + rid: ResourceId, + kind: ItemKind, + enabled: bool, +) -> crate::Result<()> { + let resources_table = app.manager.resources_table(); + do_menu_item!( + resources_table, + rid, + kind, + |i| i.set_enabled(enabled), + !Predefined + ) +} + +#[command(root = "crate")] +fn set_accelerator( + app: AppHandle, + rid: ResourceId, + kind: ItemKind, + accelerator: Option, +) -> crate::Result<()> { + let resources_table = app.manager.resources_table(); + do_menu_item!( + resources_table, + rid, + kind, + |i| i.set_accelerator(accelerator), + !Predefined | !Submenu + ) +} + +#[command(root = "crate")] +fn set_as_windows_menu_for_nsapp( + app: AppHandle, + rid: ResourceId, +) -> crate::Result<()> { + #[cfg(target_os = "macos")] + { + let resources_table = app.manager.resources_table(); + let submenu = resources_table.get::>(rid)?; + submenu.set_as_help_menu_for_nsapp()?; + } + + let _ = rid; + let _ = app; + Ok(()) +} + +#[command(root = "crate")] +fn set_as_help_menu_for_nsapp(app: AppHandle, rid: ResourceId) -> crate::Result<()> { + #[cfg(target_os = "macos")] + { + let resources_table = app.manager.resources_table(); + let submenu = resources_table.get::>(rid)?; + submenu.set_as_help_menu_for_nsapp()?; + } + + let _ = rid; + let _ = app; + + Ok(()) +} + +#[command(root = "crate")] +fn is_checked(app: AppHandle, rid: ResourceId) -> crate::Result { + let resources_table = app.manager.resources_table(); + let check_item = resources_table.get::>(rid)?; + check_item.is_checked() +} + +#[command(root = "crate")] +fn set_checked(app: AppHandle, rid: ResourceId, checked: bool) -> crate::Result<()> { + let resources_table = app.manager.resources_table(); + let check_item = resources_table.get::>(rid)?; + check_item.set_checked(checked) +} + +#[command(root = "crate")] +fn set_icon( + app: AppHandle, + rid: ResourceId, + icon: Option, +) -> crate::Result<()> { + let resources_table = app.manager.resources_table(); + let icon_item = resources_table.get::>(rid)?; + match icon { + Some(Icon::Native(icon)) => icon_item.set_native_icon(Some(icon)), + Some(Icon::Icon(icon)) => icon_item.set_icon(Some(icon.into())), + None => { + icon_item.set_icon(None)?; + icon_item.set_native_icon(None)?; + Ok(()) + } + } +} + +struct MenuChannels(Mutex>); + +pub(crate) fn init() -> TauriPlugin { + Builder::new("menu") + .setup(|app, _api| { + app.manage(MenuChannels(Mutex::default())); + Ok(()) + }) + .on_event(|app, e| { + if let RunEvent::MenuEvent(e) = e { + if let Some(channel) = app.state::().0.lock().unwrap().get(&e.id) { + let _ = channel.send(&e.id); + } + } + }) + .invoke_handler(crate::generate_handler![ + new, + append, + prepend, + insert, + remove, + remove_at, + items, + get, + popup, + default, + set_as_app_menu, + set_as_window_menu, + text, + set_text, + is_enabled, + set_enabled, + set_accelerator, + set_as_windows_menu_for_nsapp, + set_as_help_menu_for_nsapp, + is_checked, + set_checked, + set_icon, + ]) + .build() +} diff --git a/core/tauri/src/menu/predefined.rs b/core/tauri/src/menu/predefined.rs index 44c6aff01d6..19dc0bce723 100644 --- a/core/tauri/src/menu/predefined.rs +++ b/core/tauri/src/menu/predefined.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: MIT use super::AboutMetadata; -use crate::{menu::MenuId, run_main_thread, AppHandle, Manager, Runtime}; +use crate::{menu::MenuId, resources::Resource, run_main_thread, AppHandle, Manager, Runtime}; /// A predefined (native) menu item which has a predfined behavior by the OS or by this crate. pub struct PredefinedMenuItem { @@ -29,7 +29,7 @@ unsafe impl Sync for PredefinedMenuItem {} unsafe impl Send for PredefinedMenuItem {} impl super::sealed::IsMenuItemBase for PredefinedMenuItem { - fn inner(&self) -> &dyn muda::IsMenuItem { + fn inner_muda(&self) -> &dyn muda::IsMenuItem { &self.inner } } @@ -285,3 +285,5 @@ impl PredefinedMenuItem { &self.app_handle } } + +impl Resource for PredefinedMenuItem {} diff --git a/core/tauri/src/menu/submenu.rs b/core/tauri/src/menu/submenu.rs index 905f04830c9..7d51be34692 100644 --- a/core/tauri/src/menu/submenu.rs +++ b/core/tauri/src/menu/submenu.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: MIT use super::{sealed::ContextMenuBase, IsMenuItem, MenuItemKind}; -use crate::{run_main_thread, AppHandle, Manager, Position, Runtime, Window}; +use crate::{resources::Resource, run_main_thread, AppHandle, Manager, Position, Runtime, Window}; use muda::{ContextMenu, MenuId}; /// A type that is a submenu inside a [`Menu`] or [`Submenu`] @@ -33,7 +33,7 @@ impl Clone for Submenu { } impl super::sealed::IsMenuItemBase for Submenu { - fn inner(&self) -> &dyn muda::IsMenuItem { + fn inner_muda(&self) -> &dyn muda::IsMenuItem { &self.inner } } @@ -95,11 +95,11 @@ impl ContextMenuBase for Submenu { }) } - fn inner(&self) -> &dyn muda::ContextMenu { + fn inner_context(&self) -> &dyn muda::ContextMenu { &self.inner } - fn inner_owned(&self) -> Box { + fn inner_context_owned(&self) -> Box { Box::new(self.clone().inner) } } @@ -173,8 +173,10 @@ impl Submenu { /// Add a menu item to the end of this submenu. pub fn append(&self, item: &dyn IsMenuItem) -> crate::Result<()> { let kind = item.kind(); - run_main_thread!(self, |self_: Self| self_.inner.append(kind.inner().inner()))? - .map_err(Into::into) + run_main_thread!(self, |self_: Self| self_ + .inner + .append(kind.inner().inner_muda()))? + .map_err(Into::into) } /// Add menu items to the end of this submenu. It calls [`Submenu::append`] in a loop internally. @@ -190,7 +192,7 @@ impl Submenu { pub fn prepend(&self, item: &dyn IsMenuItem) -> crate::Result<()> { let kind = item.kind(); run_main_thread!(self, |self_: Self| { - self_.inner.prepend(kind.inner().inner()) + self_.inner.prepend(kind.inner().inner_muda()) })? .map_err(Into::into) } @@ -204,7 +206,7 @@ impl Submenu { pub fn insert(&self, item: &dyn IsMenuItem, position: usize) -> crate::Result<()> { let kind = item.kind(); run_main_thread!(self, |self_: Self| { - self_.inner.insert(kind.inner().inner(), position) + self_.inner.insert(kind.inner().inner_muda(), position) })? .map_err(Into::into) } @@ -221,47 +223,41 @@ impl Submenu { /// Remove a menu item from this submenu. pub fn remove(&self, item: &dyn IsMenuItem) -> crate::Result<()> { let kind = item.kind(); - run_main_thread!(self, |self_: Self| self_.inner.remove(kind.inner().inner()))? - .map_err(Into::into) + run_main_thread!(self, |self_: Self| self_ + .inner + .remove(kind.inner().inner_muda()))? + .map_err(Into::into) + } + + /// Remove the menu item at the specified position from this submenu and returns it. + pub fn remove_at(&self, position: usize) -> crate::Result>> { + run_main_thread!(self, |self_: Self| self_ + .inner + .remove_at(position) + .map(|i| MenuItemKind::from_muda(self_.app_handle.clone(), i))) + } + + /// Retrieves the menu item matching the given identifier. + pub fn get<'a, I>(&self, id: &'a I) -> Option> + where + I: ?Sized, + MenuId: PartialEq<&'a I>, + { + self + .items() + .unwrap_or_default() + .into_iter() + .find(|i| i.id() == &id) } /// Returns a list of menu items that has been added to this submenu. pub fn items(&self) -> crate::Result>> { - let handle = self.app_handle.clone(); run_main_thread!(self, |self_: Self| { self_ .inner .items() .into_iter() - .map(|i| match i { - muda::MenuItemKind::MenuItem(i) => super::MenuItemKind::MenuItem(super::MenuItem { - id: i.id().clone(), - inner: i, - app_handle: handle.clone(), - }), - muda::MenuItemKind::Submenu(i) => super::MenuItemKind::Submenu(super::Submenu { - id: i.id().clone(), - inner: i, - app_handle: handle.clone(), - }), - muda::MenuItemKind::Predefined(i) => { - super::MenuItemKind::Predefined(super::PredefinedMenuItem { - id: i.id().clone(), - inner: i, - app_handle: handle.clone(), - }) - } - muda::MenuItemKind::Check(i) => super::MenuItemKind::Check(super::CheckMenuItem { - id: i.id().clone(), - inner: i, - app_handle: handle.clone(), - }), - muda::MenuItemKind::Icon(i) => super::MenuItemKind::Icon(super::IconMenuItem { - id: i.id().clone(), - inner: i, - app_handle: handle.clone(), - }), - }) + .map(|i| MenuItemKind::from_muda(self_.app_handle.clone(), i)) .collect::>() }) } @@ -307,22 +303,11 @@ impl Submenu { /// /// If no menu is set as the Help menu, macOS will automatically use any menu /// which has a title matching the localized word "Help". + #[cfg(target_os = "macos")] pub fn set_as_help_menu_for_nsapp(&self) -> crate::Result<()> { - #[cfg(target_os = "macos")] run_main_thread!(self, |self_: Self| self_.inner.set_as_help_menu_for_nsapp())?; Ok(()) } - - /// Retrieves the menu item matching the given identifier. - pub fn get<'a, I>(&self, id: &'a I) -> Option> - where - I: ?Sized, - MenuId: PartialEq<&'a I>, - { - self - .items() - .unwrap_or_default() - .into_iter() - .find(|i| i.id() == &id) - } } + +impl Resource for Submenu {} diff --git a/core/tauri/src/resources/mod.rs b/core/tauri/src/resources/mod.rs new file mode 100644 index 00000000000..e178fed799a --- /dev/null +++ b/core/tauri/src/resources/mod.rs @@ -0,0 +1,143 @@ +// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. +// Copyright 2019-2023 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +// a modified version of https://github.com/denoland/deno/blob/0ae83847f498a2886ae32172e50fd5bdbab2f524/core/resources.rs#L220 + +pub(crate) mod plugin; + +use crate::error::Error; +use std::{ + any::{type_name, Any, TypeId}, + borrow::Cow, + collections::BTreeMap, + sync::Arc, +}; + +/// Resources are Rust objects that are stored in [ResourceTable] and managed by tauri. +/// They are identified in JS by a numeric ID (the resource ID, or rid). +/// Resources can be created in commands. Resources can also be retrieved in commands by +/// their rid. Resources are thread-safe. +/// +/// Resources are reference counted in Rust. This means that they can be +/// cloned and passed around. When the last reference is dropped, the resource +/// is automatically closed. As long as the resource exists in the resource +/// table, the reference count is at least 1. +pub(crate) trait Resource: Any + 'static + Send + Sync { + /// Returns a string representation of the resource. The default implementation + /// returns the Rust type name, but specific resource types may override this + /// trait method. + fn name(&self) -> Cow<'_, str> { + type_name::().into() + } + + /// Resources may implement the `close()` trait method if they need to do + /// resource specific clean-ups, such as cancelling pending futures, after a + /// resource has been removed from the resource table. + fn close(self: Arc) {} +} + +impl dyn Resource { + #[inline(always)] + fn is(&self) -> bool { + self.type_id() == TypeId::of::() + } + + #[inline(always)] + pub(crate) fn downcast_arc<'a, T: Resource>(self: &'a Arc) -> Option<&'a Arc> { + if self.is::() { + // A resource is stored as `Arc` in a BTreeMap + // and is safe to cast to `Arc` because of the runtime + // check done in `self.is::()` + let ptr = self as *const Arc<_> as *const Arc; + Some(unsafe { &*ptr }) + } else { + None + } + } +} + +/// A `ResourceId` is an integer value referencing a resource. It could be +/// considered to be the tauri equivalent of a `file descriptor` in POSIX like +/// operating systems. Elsewhere in the code base it is commonly abbreviated +/// to `rid`. +pub(crate) type ResourceId = u32; + +/// Map-like data structure storing Tauri's resources (equivalent to file +/// descriptors). +/// +/// Provides basic methods for element access. A resource can be of any type. +/// Different types of resources can be stored in the same map, and provided +/// with a name for description. +/// +/// Each resource is identified through a _resource ID (rid)_, which acts as +/// the key in the map. +#[derive(Default)] +pub(crate) struct ResourceTable { + pub(crate) index: BTreeMap>, + pub(crate) next_rid: ResourceId, +} + +impl ResourceTable { + /// Inserts resource into the resource table, which takes ownership of it. + /// + /// The resource type is erased at runtime and must be statically known + /// when retrieving it through `get()`. + /// + /// Returns a unique resource ID, which acts as a key for this resource. + pub(crate) fn add(&mut self, resource: T) -> ResourceId { + self.add_arc(Arc::new(resource)) + } + + /// Inserts a `Arc`-wrapped resource into the resource table. + /// + /// The resource type is erased at runtime and must be statically known + /// when retrieving it through `get()`. + /// + /// Returns a unique resource ID, which acts as a key for this resource. + pub(crate) fn add_arc(&mut self, resource: Arc) -> ResourceId { + let resource = resource as Arc; + self.add_arc_dyn(resource) + } + + pub(crate) fn add_arc_dyn(&mut self, resource: Arc) -> ResourceId { + let rid = self.next_rid; + let removed_resource = self.index.insert(rid, resource); + // TODO: add replace method if needed + assert!(removed_resource.is_none()); + self.next_rid += 1; + rid + } + + /// Returns a reference counted pointer to the resource of type `T` with the + /// given `rid`. If `rid` is not present or has a type different than `T`, + /// this function returns [`Error::BadResourceId`]. + pub(crate) fn get(&self, rid: ResourceId) -> Result, Error> { + self + .index + .get(&rid) + .and_then(|rc| rc.downcast_arc::()) + .map(Clone::clone) + .ok_or_else(|| Error::BadResourceId(rid)) + } + + /// Removes the resource with the given `rid` from the resource table. If the + /// only reference to this resource existed in the resource table, this will + /// cause the resource to be dropped. However, since resources are reference + /// counted, therefore pending ops are not automatically cancelled. A resource + /// may implement the `close()` method to perform clean-ups such as canceling + /// ops. + pub(crate) fn close(&mut self, rid: ResourceId) -> Result<(), Error> { + self + .index + .remove(&rid) + .ok_or_else(|| Error::BadResourceId(rid)) + .map(|resource| resource.close()) + } + + /// Removes and frees all resources stored. + pub(crate) fn clear(&mut self) { + self.index.clear() + } +} diff --git a/core/tauri/src/resources/plugin.rs b/core/tauri/src/resources/plugin.rs new file mode 100644 index 00000000000..1b8932e2197 --- /dev/null +++ b/core/tauri/src/resources/plugin.rs @@ -0,0 +1,22 @@ +// Copyright 2019-2023 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use crate::{ + command, + plugin::{Builder, TauriPlugin}, + AppHandle, Runtime, +}; + +use super::ResourceId; + +#[command(root = "crate")] +fn close(app: AppHandle, rid: ResourceId) -> crate::Result<()> { + app.manager.resources_table().close(rid) +} + +pub(crate) fn init() -> TauriPlugin { + Builder::new("resources") + .invoke_handler(crate::generate_handler![close]) + .build() +} diff --git a/core/tauri/src/tray.rs b/core/tauri/src/tray/mod.rs similarity index 93% rename from core/tauri/src/tray.rs rename to core/tauri/src/tray/mod.rs index 450a4f95068..11db0bb97db 100644 --- a/core/tauri/src/tray.rs +++ b/core/tauri/src/tray/mod.rs @@ -4,19 +4,21 @@ #![cfg(all(desktop, feature = "tray-icon"))] -//! Tray icon types and utility functions +//! Tray icon types and utilities. + +pub(crate) mod plugin; use crate::app::{GlobalMenuEventListener, GlobalTrayIconEventListener}; use crate::menu::ContextMenu; use crate::menu::MenuEvent; +use crate::resources::Resource; use crate::{run_main_thread, AppHandle, Icon, Manager, Runtime}; +use serde::Serialize; use std::path::Path; pub use tray_icon::TrayIconId; -// TODO(muda-migration): figure out js events - /// Describes a rectangle including position (x - y axis) and size. -#[derive(Debug, PartialEq, Clone, Copy, Default)] +#[derive(Debug, PartialEq, Clone, Copy, Default, Serialize)] pub struct Rectangle { /// The x-coordinate of the upper-left corner of the rectangle. pub left: f64, @@ -29,7 +31,7 @@ pub struct Rectangle { } /// Describes the click type that triggered this tray icon event. -#[derive(Clone, Copy, PartialEq, Eq, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, Debug, Serialize)] pub enum ClickType { /// Left mouse click. Left, @@ -51,7 +53,8 @@ impl Default for ClickType { /// /// - **Linux**: Unsupported. The event is not emmited even though the icon is shown, /// the icon will still show a context menu on right click. -#[derive(Debug, Clone, Default)] +#[derive(Debug, Clone, Default, Serialize)] +#[serde(rename_all = "camelCase")] pub struct TrayIconEvent { /// Id of the tray icon which triggered this event. pub id: TrayIconId, @@ -146,7 +149,7 @@ impl TrayIconBuilder { /// /// - **Linux**: once a menu is set, it cannot be removed or replaced but you can change its content. pub fn menu(mut self, menu: &M) -> Self { - self.inner = self.inner.with_menu(menu.inner_owned()); + self.inner = self.inner.with_menu(menu.inner_context_owned()); self } @@ -360,13 +363,13 @@ impl TrayIcon { &self.id } - /// Set new tray icon. If `None` is provided, it will remove the icon. + /// Sets a new tray icon. If `None` is provided, it will remove the icon. pub fn set_icon(&self, icon: Option) -> crate::Result<()> { let icon = icon.and_then(|i| i.try_into().ok()); run_main_thread!(self, |self_: Self| self_.inner.set_icon(icon))?.map_err(Into::into) } - /// Set new tray menu. + /// Sets a new tray menu. /// /// ## Platform-specific: /// @@ -374,7 +377,7 @@ impl TrayIcon { pub fn set_menu(&self, menu: Option) -> crate::Result<()> { run_main_thread!(self, |self_: Self| self_ .inner - .set_menu(menu.map(|m| m.inner_owned()))) + .set_menu(menu.map(|m| m.inner_context_owned()))) } /// Sets the tooltip for this tray icon. @@ -387,7 +390,7 @@ impl TrayIcon { run_main_thread!(self, |self_: Self| self_.inner.set_tooltip(s))?.map_err(Into::into) } - /// Sets the tooltip for this tray icon. + /// Sets the title for this tray icon. /// /// ## Platform-specific: /// @@ -402,7 +405,7 @@ impl TrayIcon { run_main_thread!(self, |self_: Self| self_.inner.set_title(s)) } - /// Show or hide this tray icon + /// Show or hide this tray icon. pub fn set_visible(&self, visible: bool) -> crate::Result<()> { run_main_thread!(self, |self_: Self| self_.inner.set_visible(visible))?.map_err(Into::into) } @@ -419,7 +422,7 @@ impl TrayIcon { Ok(()) } - /// Set the current icon as a [template](https://developer.apple.com/documentation/appkit/nsimage/1520017-template?language=objc). **macOS only**. + /// Sets the current icon as a [template](https://developer.apple.com/documentation/appkit/nsimage/1520017-template?language=objc). **macOS only**. pub fn set_icon_as_template(&self, #[allow(unused)] is_template: bool) -> crate::Result<()> { #[cfg(target_os = "macos")] run_main_thread!(self, |self_: Self| self_ @@ -446,3 +449,9 @@ impl TryFrom for tray_icon::Icon { tray_icon::Icon::from_rgba(value.rgba, value.width, value.height).map_err(Into::into) } } + +impl Resource for TrayIcon { + fn close(self: std::sync::Arc) { + self.app_handle.remove_tray_by_id(&self.id); + } +} diff --git a/core/tauri/src/tray/plugin.rs b/core/tauri/src/tray/plugin.rs new file mode 100644 index 00000000000..03d4ebd55e6 --- /dev/null +++ b/core/tauri/src/tray/plugin.rs @@ -0,0 +1,204 @@ +// Copyright 2019-2023 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +use std::path::PathBuf; + +use serde::Deserialize; + +use crate::{ + command, + ipc::Channel, + menu::{plugin::ItemKind, Menu, Submenu}, + plugin::{Builder, TauriPlugin}, + resources::ResourceId, + tray::TrayIconBuilder, + AppHandle, IconDto, Runtime, +}; + +use super::TrayIcon; + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct TrayIconOptions { + id: Option, + menu: Option<(ResourceId, ItemKind)>, + icon: Option, + tooltip: Option, + title: Option, + temp_dir_path: Option, + icon_as_template: Option, + menu_on_left_click: Option, +} + +#[command(root = "crate")] +fn new( + app: AppHandle, + options: TrayIconOptions, + handler: Channel, +) -> crate::Result<(ResourceId, String)> { + let mut builder = if let Some(id) = options.id { + TrayIconBuilder::::with_id(id) + } else { + TrayIconBuilder::::new() + }; + + builder = builder.on_tray_icon_event(move |_tray, e| { + let _ = handler.send(e); + }); + + let mut resources_table = app.manager.resources_table(); + + if let Some((rid, kind)) = options.menu { + match kind { + ItemKind::Menu => { + let menu = resources_table.get::>(rid)?; + builder = builder.menu(&*menu); + } + ItemKind::Submenu => { + let submenu = resources_table.get::>(rid)?; + builder = builder.menu(&*submenu); + } + _ => return Err(anyhow::anyhow!("unexpected menu item kind").into()), + }; + } + if let Some(icon) = options.icon { + builder = builder.icon(icon.into()); + } + if let Some(tooltip) = options.tooltip { + builder = builder.tooltip(tooltip); + } + if let Some(title) = options.title { + builder = builder.title(title); + } + if let Some(temp_dir_path) = options.temp_dir_path { + builder = builder.temp_dir_path(temp_dir_path); + } + if let Some(icon_as_template) = options.icon_as_template { + builder = builder.icon_as_template(icon_as_template); + } + if let Some(menu_on_left_click) = options.menu_on_left_click { + builder = builder.menu_on_left_click(menu_on_left_click); + } + + let tray = builder.build(&app)?; + let id = tray.id().as_ref().to_string(); + let rid = resources_table.add(tray); + + Ok((rid, id)) +} + +#[command(root = "crate")] +fn set_icon( + app: AppHandle, + rid: ResourceId, + icon: Option, +) -> crate::Result<()> { + let resources_table = app.manager.resources_table(); + let tray = resources_table.get::>(rid)?; + tray.set_icon(icon.map(Into::into)) +} + +#[command(root = "crate")] +fn set_menu( + app: AppHandle, + rid: ResourceId, + menu: Option<(ResourceId, ItemKind)>, +) -> crate::Result<()> { + let resources_table = app.manager.resources_table(); + let tray = resources_table.get::>(rid)?; + if let Some((rid, kind)) = menu { + match kind { + ItemKind::Menu => { + let menu = resources_table.get::>(rid)?; + tray.set_menu(Some((*menu).clone()))?; + } + ItemKind::Submenu => { + let submenu = resources_table.get::>(rid)?; + tray.set_menu(Some((*submenu).clone()))?; + } + _ => return Err(anyhow::anyhow!("unexpected menu item kind").into()), + }; + } else { + tray.set_menu(None::>)?; + } + Ok(()) +} + +#[command(root = "crate")] +fn set_tooltip( + app: AppHandle, + rid: ResourceId, + tooltip: Option, +) -> crate::Result<()> { + let resources_table = app.manager.resources_table(); + let tray = resources_table.get::>(rid)?; + tray.set_tooltip(tooltip) +} + +#[command(root = "crate")] +fn set_title( + app: AppHandle, + rid: ResourceId, + title: Option, +) -> crate::Result<()> { + let resources_table = app.manager.resources_table(); + let tray = resources_table.get::>(rid)?; + tray.set_title(title) +} + +#[command(root = "crate")] +fn set_visible(app: AppHandle, rid: ResourceId, visible: bool) -> crate::Result<()> { + let resources_table = app.manager.resources_table(); + let tray = resources_table.get::>(rid)?; + tray.set_visible(visible) +} + +#[command(root = "crate")] +fn set_temp_dir_path( + app: AppHandle, + rid: ResourceId, + path: Option, +) -> crate::Result<()> { + let resources_table = app.manager.resources_table(); + let tray = resources_table.get::>(rid)?; + tray.set_temp_dir_path(path) +} + +#[command(root = "crate")] +fn set_icon_as_template( + app: AppHandle, + rid: ResourceId, + as_template: bool, +) -> crate::Result<()> { + let resources_table = app.manager.resources_table(); + let tray = resources_table.get::>(rid)?; + tray.set_icon_as_template(as_template) +} + +#[command(root = "crate")] +fn set_show_menu_on_left_click( + app: AppHandle, + rid: ResourceId, + on_left: bool, +) -> crate::Result<()> { + let resources_table = app.manager.resources_table(); + let tray = resources_table.get::>(rid)?; + tray.set_show_menu_on_left_click(on_left) +} + +pub(crate) fn init() -> TauriPlugin { + Builder::new("tray") + .invoke_handler(crate::generate_handler![ + new, + set_icon, + set_menu, + set_tooltip, + set_title, + set_visible, + set_temp_dir_path, + set_icon_as_template, + set_show_menu_on_left_click, + ]) + .build() +} diff --git a/core/tauri/src/window/mod.rs b/core/tauri/src/window/mod.rs index 217c83d4469..6ec2b8fe0e0 100644 --- a/core/tauri/src/window/mod.rs +++ b/core/tauri/src/window/mod.rs @@ -1411,12 +1411,13 @@ impl Window { /// - **macOS:** Unsupported. The menu on macOS is app-wide and not specific to one /// window, if you need to remove it, use [`AppHandle::remove_menu`] instead. pub fn remove_menu(&self) -> crate::Result>> { - let current_menu = self.menu_lock().as_ref().map(|m| m.menu.clone()); + let prev_menu = self.menu_lock().take().map(|m| m.menu); // remove from the window #[cfg_attr(target_os = "macos", allow(unused_variables))] - if let Some(menu) = current_menu { + if let Some(menu) = &prev_menu { let window = self.clone(); + let menu = menu.clone(); self.run_on_main_thread(move || { #[cfg(windows)] if let Ok(hwnd) = window.hwnd() { @@ -1435,8 +1436,6 @@ impl Window { })?; } - let prev_menu = self.menu_lock().take().map(|m| m.menu); - self .manager .remove_menu_from_stash_by_id(prev_menu.as_ref().map(|m| m.id())); @@ -2287,12 +2286,13 @@ impl Window { handled = true; fn load_channels(payload: &serde_json::Value, window: &Window) { + use std::str::FromStr; + if let serde_json::Value::Object(map) = payload { for v in map.values() { if let serde_json::Value::String(s) = v { - if s.starts_with(crate::ipc::channel::IPC_PAYLOAD_PREFIX) { - crate::ipc::Channel::load_from_ipc(window.clone(), s); - } + crate::ipc::JavaScriptChannelId::from_str(s) + .map(|id| id.channel_on(window.clone())); } } } diff --git a/examples/api/README.md b/examples/api/README.md index d9fe94b1f47..c0cba6e1a21 100644 --- a/examples/api/README.md +++ b/examples/api/README.md @@ -1,4 +1,5 @@ # API example + This example demonstrates Tauri's API capabilities using the `@tauri-apps/api` package. It's used as the main validation app, serving as the testbed of our development process. In the future, this app will be used on Tauri's integration tests. @@ -7,19 +8,22 @@ In the future, this app will be used on Tauri's integration tests. ## Running the example - Compile Tauri -go to root of the Tauri repo and run: -Linux / Mac: + go to root of the Tauri repo and run: + Linux / Mac: + ``` # choose to install node cli (1) bash .scripts/setup.sh ``` Windows: + ``` ./.scripts/setup.ps1 ``` - Install dependencies (Run inside of this folder `examples/api/`) + ```bash # with yarn $ yarn @@ -28,6 +32,7 @@ $ npm install ``` - Run the app in development mode (Run inside of this folder `examples/api/`) + ```bash # with yarn $ yarn tauri dev @@ -36,6 +41,7 @@ $ npm run tauri dev ``` - Build an run the release app (Run inside of this folder `examples/api/`) + ```bash $ yarn tauri build $ ./src-tauri/target/release/app diff --git a/examples/api/dist/assets/index.css b/examples/api/dist/assets/index.css index 8723712d01f..f256b138469 100644 --- a/examples/api/dist/assets/index.css +++ b/examples/api/dist/assets/index.css @@ -1 +1 @@ -*,::before,::after{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x:var(--un-empty,/*!*/ /*!*/);--un-pan-y:var(--un-empty,/*!*/ /*!*/);--un-pinch-zoom:var(--un-empty,/*!*/ /*!*/);--un-scroll-snap-strictness:proximity;--un-ordinal:var(--un-empty,/*!*/ /*!*/);--un-slashed-zero:var(--un-empty,/*!*/ /*!*/);--un-numeric-figure:var(--un-empty,/*!*/ /*!*/);--un-numeric-spacing:var(--un-empty,/*!*/ /*!*/);--un-numeric-fraction:var(--un-empty,/*!*/ /*!*/);--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 #0000;--un-ring-shadow:0 0 #0000;--un-shadow-inset:var(--un-empty,/*!*/ /*!*/);--un-shadow:0 0 #0000;--un-ring-inset:var(--un-empty,/*!*/ /*!*/);--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgba(147,197,253,0.5);--un-blur:var(--un-empty,/*!*/ /*!*/);--un-brightness:var(--un-empty,/*!*/ /*!*/);--un-contrast:var(--un-empty,/*!*/ /*!*/);--un-drop-shadow:var(--un-empty,/*!*/ /*!*/);--un-grayscale:var(--un-empty,/*!*/ /*!*/);--un-hue-rotate:var(--un-empty,/*!*/ /*!*/);--un-invert:var(--un-empty,/*!*/ /*!*/);--un-saturate:var(--un-empty,/*!*/ /*!*/);--un-sepia:var(--un-empty,/*!*/ /*!*/);--un-backdrop-blur:var(--un-empty,/*!*/ /*!*/);--un-backdrop-brightness:var(--un-empty,/*!*/ /*!*/);--un-backdrop-contrast:var(--un-empty,/*!*/ /*!*/);--un-backdrop-grayscale:var(--un-empty,/*!*/ /*!*/);--un-backdrop-hue-rotate:var(--un-empty,/*!*/ /*!*/);--un-backdrop-invert:var(--un-empty,/*!*/ /*!*/);--un-backdrop-opacity:var(--un-empty,/*!*/ /*!*/);--un-backdrop-saturate:var(--un-empty,/*!*/ /*!*/);--un-backdrop-sepia:var(--un-empty,/*!*/ /*!*/);}@font-face { font-family: 'Fira Code'; font-style: normal; font-weight: 400; font-display: swap; src: url(https://fonts.gstatic.com/s/firacode/v22/uU9eCBsR6Z2vfE9aq3bL0fxyUs4tcw4W_D1sFVc.ttf) format('truetype');}@font-face { font-family: 'Fira Mono'; font-style: normal; font-weight: 400; font-display: swap; src: url(https://fonts.gstatic.com/s/firamono/v14/N0bX2SlFPv1weGeLZDtQIQ.ttf) format('truetype');}@font-face { font-family: 'Fira Mono'; font-style: normal; font-weight: 700; font-display: swap; src: url(https://fonts.gstatic.com/s/firamono/v14/N0bS2SlFPv1weGeLZDtondv3mQ.ttf) format('truetype');}@font-face { font-family: 'Rubik'; font-style: normal; font-weight: 400; font-display: swap; src: url(https://fonts.gstatic.com/s/rubik/v28/iJWZBXyIfDnIV5PNhY1KTN7Z-Yh-B4i1UA.ttf) format('truetype');}.i-codicon-clear-all{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 16 16' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='m10 12.6l.7.7l1.6-1.6l1.6 1.6l.8-.7L13 11l1.7-1.6l-.8-.8l-1.6 1.7l-1.6-1.7l-.7.8l1.6 1.6l-1.6 1.6zM1 4h14V3H1v1zm0 3h14V6H1v1zm8 2.5V9H1v1h8v-.5zM9 13v-1H1v1h8z'/%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-codicon-close{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 16 16' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' fill-rule='evenodd' d='m8 8.707l3.646 3.647l.708-.707L8.707 8l3.647-3.646l-.707-.708L8 7.293L4.354 3.646l-.707.708L7.293 8l-3.646 3.646l.707.708L8 8.707z' clip-rule='evenodd'/%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-codicon-hubot{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 16 16' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' fill-rule='evenodd' d='M8.48 4h4l.5.5v2.03h.52l.5.5V8l-.5.5h-.52v3l-.5.5H9.36l-2.5 2.76L6 14.4V12H3.5l-.5-.64V8.5h-.5L2 8v-.97l.5-.5H3V4.36L3.53 4h4V2.86A1 1 0 0 1 7 2a1 1 0 0 1 2 0a1 1 0 0 1-.52.83V4zM12 8V5H4v5.86l2.5.14H7v2.19l1.8-2.04l.35-.15H12V8zm-2.12.51a2.71 2.71 0 0 1-1.37.74v-.01a2.71 2.71 0 0 1-2.42-.74l-.7.71c.34.34.745.608 1.19.79c.45.188.932.286 1.42.29a3.7 3.7 0 0 0 2.58-1.07l-.7-.71zM6.49 6.5h-1v1h1v-1zm3 0h1v1h-1v-1z' clip-rule='evenodd'/%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-codicon-link-external{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 16 16' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M1.5 1H6v1H2v12h12v-4h1v4.5l-.5.5h-13l-.5-.5v-13l.5-.5z'/%3E%3Cpath d='M15 1.5V8h-1V2.707L7.243 9.465l-.707-.708L13.293 2H8V1h6.5l.5.5z'/%3E%3C/g%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-codicon-menu{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 16 16' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M16 5H0V4h16v1zm0 8H0v-1h16v1zm0-4.008H0V8h16v.992z'/%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-codicon-radio-tower{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 16 16' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' fill-rule='evenodd' d='M2.998 5.58a5.55 5.55 0 0 1 1.62-3.88l-.71-.7a6.45 6.45 0 0 0 0 9.16l.71-.7a5.55 5.55 0 0 1-1.62-3.88zm1.06 0a4.42 4.42 0 0 0 1.32 3.17l.71-.71a3.27 3.27 0 0 1-.76-1.12a3.45 3.45 0 0 1 0-2.67a3.22 3.22 0 0 1 .76-1.13l-.71-.71a4.46 4.46 0 0 0-1.32 3.17zm7.65 3.21l-.71-.71c.33-.32.59-.704.76-1.13a3.449 3.449 0 0 0 0-2.67a3.22 3.22 0 0 0-.76-1.13l.71-.7a4.468 4.468 0 0 1 0 6.34zM13.068 1l-.71.71a5.43 5.43 0 0 1 0 7.74l.71.71a6.45 6.45 0 0 0 0-9.16zM9.993 5.43a1.5 1.5 0 0 1-.245.98a2 2 0 0 1-.27.23l3.44 7.73l-.92.4l-.77-1.73h-5.54l-.77 1.73l-.92-.4l3.44-7.73a1.52 1.52 0 0 1-.33-1.63a1.55 1.55 0 0 1 .56-.68a1.5 1.5 0 0 1 2.325 1.1zm-1.595-.34a.52.52 0 0 0-.25.14a.52.52 0 0 0-.11.22a.48.48 0 0 0 0 .29c.04.09.102.17.18.23a.54.54 0 0 0 .28.08a.51.51 0 0 0 .5-.5a.54.54 0 0 0-.08-.28a.58.58 0 0 0-.23-.18a.48.48 0 0 0-.29 0zm.23 2.05h-.27l-.87 1.94h2l-.86-1.94zm2.2 4.94l-.89-2h-2.88l-.89 2h4.66z' clip-rule='evenodd'/%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-codicon-window{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 16 16' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M14.5 2h-13l-.5.5v11l.5.5h13l.5-.5v-11l-.5-.5zM14 13H2V6h12v7zm0-8H2V3h12v2z'/%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-ph-broadcast{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M128 88a40 40 0 1 0 40 40a40 40 0 0 0-40-40Zm0 64a24 24 0 1 1 24-24a24.1 24.1 0 0 1-24 24Zm-59-48.9a64.5 64.5 0 0 0 0 49.8a65.4 65.4 0 0 0 13.7 20.4a7.9 7.9 0 0 1 0 11.3a8 8 0 0 1-5.6 2.3a8.3 8.3 0 0 1-5.7-2.3a80 80 0 0 1-17.1-25.5a79.9 79.9 0 0 1 0-62.2a80 80 0 0 1 17.1-25.5a8 8 0 0 1 11.3 0a7.9 7.9 0 0 1 0 11.3A65.4 65.4 0 0 0 69 103.1Zm132.7 56a80 80 0 0 1-17.1 25.5a8.3 8.3 0 0 1-5.7 2.3a8 8 0 0 1-5.6-2.3a7.9 7.9 0 0 1 0-11.3a65.4 65.4 0 0 0 13.7-20.4a64.5 64.5 0 0 0 0-49.8a65.4 65.4 0 0 0-13.7-20.4a7.9 7.9 0 0 1 0-11.3a8 8 0 0 1 11.3 0a80 80 0 0 1 17.1 25.5a79.9 79.9 0 0 1 0 62.2ZM54.5 201.5a8.1 8.1 0 0 1 0 11.4a8.3 8.3 0 0 1-5.7 2.3a8.5 8.5 0 0 1-5.7-2.3a121.8 121.8 0 0 1-25.7-38.2a120.7 120.7 0 0 1 0-93.4a121.8 121.8 0 0 1 25.7-38.2a8.1 8.1 0 0 1 11.4 11.4A103.5 103.5 0 0 0 24 128a103.5 103.5 0 0 0 30.5 73.5ZM248 128a120.2 120.2 0 0 1-9.4 46.7a121.8 121.8 0 0 1-25.7 38.2a8.5 8.5 0 0 1-5.7 2.3a8.3 8.3 0 0 1-5.7-2.3a8.1 8.1 0 0 1 0-11.4A103.5 103.5 0 0 0 232 128a103.5 103.5 0 0 0-30.5-73.5a8.1 8.1 0 1 1 11.4-11.4a121.8 121.8 0 0 1 25.7 38.2A120.2 120.2 0 0 1 248 128Z'/%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-ph-hand-waving{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='m220.2 104l-20-34.7a28.1 28.1 0 0 0-47.3-1.9l-17.3-30a28.1 28.1 0 0 0-38.3-10.3a29.4 29.4 0 0 0-9.9 9.6a27.9 27.9 0 0 0-11.5-6.2a27.2 27.2 0 0 0-21.2 2.8a27.9 27.9 0 0 0-10.3 38.2l3.4 5.8A28.5 28.5 0 0 0 36 81a28.1 28.1 0 0 0-10.2 38.2l42 72.8a88 88 0 1 0 152.4-88Zm-6.7 62.6a71.2 71.2 0 0 1-33.5 43.7A72.1 72.1 0 0 1 81.6 184l-42-72.8a12 12 0 0 1 20.8-12l22 38.1l.6.9v.2l.5.5l.2.2l.7.6h.1l.7.5h.3l.6.3h.2l.9.3h.1l.8.2h2.2l.9-.2h.3l.6-.2h.3l.9-.4a8.1 8.1 0 0 0 2.9-11l-22-38.1l-16-27.7a12 12 0 0 1-1.2-9.1a11.8 11.8 0 0 1 5.6-7.3a12 12 0 0 1 9.1-1.2a12.5 12.5 0 0 1 7.3 5.6l8 14h.1l26 45a7 7 0 0 0 1.5 1.9a8 8 0 0 0 12.3-9.9l-26-45a12 12 0 1 1 20.8-12l30 51.9l6.3 11a48.1 48.1 0 0 0-10.9 61a8 8 0 0 0 13.8-8a32 32 0 0 1 11.7-43.7l.7-.4l.5-.4h.1l.6-.6l.5-.5l.4-.5l.3-.6h.1l.2-.5v-.2a1.9 1.9 0 0 0 .2-.7h.1c0-.2.1-.4.1-.6s0-.2.1-.2v-2.1a6.4 6.4 0 0 0-.2-.7a1.9 1.9 0 0 0-.2-.7v-.2c0-.2-.1-.3-.2-.5l-.3-.7l-10-17.4a12 12 0 0 1 13.5-17.5a11.8 11.8 0 0 1 7.2 5.5l20 34.7a70.9 70.9 0 0 1 7.2 53.8Zm-125.8 78a8.2 8.2 0 0 1-6.6 3.4a8.6 8.6 0 0 1-4.6-1.4A117.9 117.9 0 0 1 41.1 208a8 8 0 1 1 13.8-8a102.6 102.6 0 0 0 30.8 33.4a8.1 8.1 0 0 1 2 11.2ZM168 31a8 8 0 0 1 8-8a60.2 60.2 0 0 1 52 30a7.9 7.9 0 0 1-3 10.9a7.1 7.1 0 0 1-4 1.1a8 8 0 0 1-6.9-4A44 44 0 0 0 176 39a8 8 0 0 1-8-8Z'/%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-ph-moon{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M224.3 150.3a8.1 8.1 0 0 0-7.8-5.7l-2.2.4A84 84 0 0 1 111 41.6a5.7 5.7 0 0 0 .3-1.8a7.9 7.9 0 0 0-10.3-8.1a100 100 0 1 0 123.3 123.2a7.2 7.2 0 0 0 0-4.6ZM128 212A84 84 0 0 1 92.8 51.7a99.9 99.9 0 0 0 111.5 111.5A84.4 84.4 0 0 1 128 212Z'/%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-ph-sun{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M128 60a68 68 0 1 0 68 68a68.1 68.1 0 0 0-68-68Zm0 120a52 52 0 1 1 52-52a52 52 0 0 1-52 52Zm-8-144V16a8 8 0 0 1 16 0v20a8 8 0 0 1-16 0ZM43.1 54.5a8.1 8.1 0 1 1 11.4-11.4l14.1 14.2a8 8 0 0 1 0 11.3a8.1 8.1 0 0 1-11.3 0ZM36 136H16a8 8 0 0 1 0-16h20a8 8 0 0 1 0 16Zm32.6 51.4a8 8 0 0 1 0 11.3l-14.1 14.2a8.3 8.3 0 0 1-5.7 2.3a8.5 8.5 0 0 1-5.7-2.3a8.1 8.1 0 0 1 0-11.4l14.2-14.1a8 8 0 0 1 11.3 0ZM136 220v20a8 8 0 0 1-16 0v-20a8 8 0 0 1 16 0Zm76.9-18.5a8.1 8.1 0 0 1 0 11.4a8.5 8.5 0 0 1-5.7 2.3a8.3 8.3 0 0 1-5.7-2.3l-14.1-14.2a8 8 0 0 1 11.3-11.3ZM248 128a8 8 0 0 1-8 8h-20a8 8 0 0 1 0-16h20a8 8 0 0 1 8 8Zm-60.6-59.4a8 8 0 0 1 0-11.3l14.1-14.2a8.1 8.1 0 0 1 11.4 11.4l-14.2 14.1a8.1 8.1 0 0 1-11.3 0Z'/%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.note-red{position:relative;display:inline-flex;align-items:center;border-left-width:4px;border-left-style:solid;--un-border-opacity:1;border-color:rgba(53,120,229,var(--un-border-opacity));border-radius:0.25rem;background-color:rgba(53,120,229,0.1);background-color:rgba(185,28,28,0.1);padding:0.5rem;text-decoration:none;}.nv{position:relative;display:flex;align-items:center;border-radius:0.25rem;padding:0.5rem;--un-text-opacity:1;color:rgba(194,197,202,var(--un-text-opacity));text-decoration:none;transition-property:all;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:125ms;}.nv_selected{position:relative;display:flex;align-items:center;border-left-width:4px;border-left-style:solid;border-radius:0.25rem;--un-bg-opacity:.05;background-color:hsla(0,0%,100%,var(--un-bg-opacity));padding:0.5rem;--un-text-opacity:1;color:rgba(194,197,202,var(--un-text-opacity));color:rgba(53,120,229,var(--un-text-opacity));text-decoration:none;transition-property:all;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:125ms;}.input{height:2.5rem;display:flex;align-items:center;border-radius:0.25rem;border-style:none;--un-bg-opacity:1;background-color:rgba(233,236,239,var(--un-bg-opacity));padding:0.5rem;--un-text-opacity:1;color:rgba(28,30,33,var(--un-text-opacity));--un-shadow:var(--un-shadow-inset) 0 4px 6px -1px var(--un-shadow-color, rgba(0,0,0,0.1)),var(--un-shadow-inset) 0 2px 4px -2px var(--un-shadow-color, rgba(0,0,0,0.1));box-shadow:var(--un-ring-offset-shadow, 0 0 #0000), var(--un-ring-shadow, 0 0 #0000), var(--un-shadow);outline:2px solid transparent;outline-offset:2px;}.btn{user-select:none;border-radius:0.25rem;border-style:none;--un-bg-opacity:1;background-color:rgba(53,120,229,var(--un-bg-opacity));padding:0.5rem;font-weight:400;--un-text-opacity:1;color:rgba(28,30,33,var(--un-text-opacity));color:rgba(255,255,255,var(--un-text-opacity));--un-shadow:var(--un-shadow-inset) 0 4px 6px -1px var(--un-shadow-color, rgba(0,0,0,0.1)),var(--un-shadow-inset) 0 2px 4px -2px var(--un-shadow-color, rgba(0,0,0,0.1));box-shadow:var(--un-ring-offset-shadow, 0 0 #0000), var(--un-ring-shadow, 0 0 #0000), var(--un-shadow);outline:2px solid transparent;outline-offset:2px;}.nv_selected:hover,.nv:hover{border-left-width:4px;border-left-style:solid;--un-bg-opacity:.05;background-color:hsla(0,0%,100%,var(--un-bg-opacity));--un-text-opacity:1;color:rgba(53,120,229,var(--un-text-opacity));}.dark .note-red{--un-border-opacity:1;border-color:rgba(103,214,237,var(--un-border-opacity));background-color:rgba(103,214,237,0.1);background-color:rgba(185,28,28,0.1);}.btn:hover{--un-bg-opacity:1;background-color:rgba(45,102,195,var(--un-bg-opacity));}.dark .btn{--un-bg-opacity:1;background-color:rgba(103,214,237,var(--un-bg-opacity));font-weight:600;--un-text-opacity:1;color:rgba(28,30,33,var(--un-text-opacity));}.dark .btn:hover{--un-bg-opacity:1;background-color:rgba(57,202,232,var(--un-bg-opacity));}.dark .input{--un-bg-opacity:1;background-color:rgba(36,37,38,var(--un-bg-opacity));--un-text-opacity:1;color:rgba(227,227,227,var(--un-text-opacity));}.dark .note-red::after,.note-red::after{--un-bg-opacity:1;background-color:rgba(185,28,28,var(--un-bg-opacity));}.btn:active{--un-bg-opacity:1;background-color:rgba(37,84,160,var(--un-bg-opacity));}.dark .btn:active{--un-bg-opacity:1;background-color:rgba(25,181,213,var(--un-bg-opacity));}.dark .nv_selected,.dark .nv_selected:hover,.dark .nv:hover{--un-text-opacity:1;color:rgba(103,214,237,var(--un-text-opacity));} ::-webkit-scrollbar-thumb { background-color: #3578E5; } .dark ::-webkit-scrollbar-thumb { background-color: #67d6ed; } code { font-size: 0.75rem; font-family: "Fira Code","Fira Mono",ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; border-radius: 0.25rem; background-color: #d6d8da; } .code-block { font-family: "Fira Code","Fira Mono",ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; font-size: 0.875rem; } .dark code { background-color: #282a2e; } .visible{visibility:visible;}.absolute{position:absolute;}.left-2{left:0.5rem;}.top-2{top:0.5rem;}.z-2000{z-index:2000;}.grid{display:grid;}.grid-rows-\[2fr_auto\]{grid-template-rows:2fr auto;}.grid-rows-\[2px_2rem_1fr\]{grid-template-rows:2px 2rem 1fr;}.grid-rows-\[auto_1fr\]{grid-template-rows:auto 1fr;}.grid-rows-\[min-content_auto\]{grid-template-rows:min-content auto;}.mb-2{margin-bottom:0.5rem;}.mr-2{margin-right:0.5rem;}.display-none{display:none;}.children-h-10>*{height:2.5rem;}.h-15rem{height:15rem;}.h-2px{height:2px;}.h-8{height:2rem;}.h-85\%{height:85%;}.h-screen{height:100vh;}.w-8{width:2rem;}.w-screen{width:100vw;}.flex{display:flex;}.flex-1{flex:1 1 0%;}.children-flex-none>*{flex:none;}.children\:grow>*,.grow{flex-grow:1;}.flex-row{flex-direction:row;}.flex-col{flex-direction:column;}.flex-wrap{flex-wrap:wrap;}@keyframes fade-in{from{opacity:0}to{opacity:1}}.animate-fade-in{animation:fade-in 1s linear 1;}.animate-duration-300ms{animation-duration:300ms;}.cursor-ns-resize{cursor:ns-resize;}.cursor-pointer{cursor:pointer;}.select-none{user-select:none;}.items-center{align-items:center;}.self-center{align-self:center;}.justify-center{justify-content:center;}.justify-between{justify-content:space-between;}.gap-1{grid-gap:0.25rem;gap:0.25rem;}.gap-2{grid-gap:0.5rem;gap:0.5rem;}.overflow-hidden{overflow:hidden;}.overflow-y-auto{overflow-y:auto;}.b{border-width:1px;border-style:solid;}.rd-1{border-radius:0.25rem;}.rd-8{border-radius:2rem;}.bg-accent{--un-bg-opacity:1;background-color:rgba(53,120,229,var(--un-bg-opacity));}.bg-black\/20{background-color:rgba(0,0,0,0.2);}.bg-darkPrimaryLighter{--un-bg-opacity:1;background-color:rgba(36,37,38,var(--un-bg-opacity));}.bg-primary{--un-bg-opacity:1;background-color:rgba(255,255,255,var(--un-bg-opacity));}.bg-white\/5{background-color:rgba(255,255,255,0.05);}.dark .dark\:bg-darkAccent{--un-bg-opacity:1;background-color:rgba(103,214,237,var(--un-bg-opacity));}.dark .dark\:bg-darkPrimary{--un-bg-opacity:1;background-color:rgba(27,27,29,var(--un-bg-opacity));}.dark .dark\:hover\:bg-darkHoverOverlay:hover{--un-bg-opacity:.05;background-color:hsla(0,0%,100%,var(--un-bg-opacity));}.hover\:bg-hoverOverlay:hover{--un-bg-opacity:.05;background-color:rgba(0,0,0,var(--un-bg-opacity));}.active\:bg-accentDark:active{--un-bg-opacity:1;background-color:rgba(48,108,206,var(--un-bg-opacity));}.active\:bg-hoverOverlay\/25:active{background-color:rgba(0,0,0,0.25);}.dark .dark\:active\:bg-darkAccentDark:active{--un-bg-opacity:1;background-color:rgba(73,206,233,var(--un-bg-opacity));}.dark .dark\:active\:bg-darkHoverOverlay\/25:active{background-color:hsla(0,0%,100%,0.25);}.p-1{padding:0.25rem;}.p-7{padding:1.75rem;}.px{padding-left:1rem;padding-right:1rem;}.px-2{padding-left:0.5rem;padding-right:0.5rem;}.px-5{padding-left:1.25rem;padding-right:1.25rem;}.children-pb-2>*{padding-bottom:0.5rem;}.children-pt8>*{padding-top:2rem;}.all\:font-mono *{font-family:"Fira Code","Fira Mono",ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;}.all\:text-xs *{font-size:0.75rem;line-height:1rem;}.text-sm{font-size:0.875rem;line-height:1.25rem;}.font-700{font-weight:700;}.font-semibold{font-weight:600;}.dark .dark\:text-darkAccent{--un-text-opacity:1;color:rgba(103,214,237,var(--un-text-opacity));}.dark .dark\:text-darkPrimaryText{--un-text-opacity:1;color:rgba(227,227,227,var(--un-text-opacity));}.text-accent{--un-text-opacity:1;color:rgba(53,120,229,var(--un-text-opacity));}.text-primaryText{--un-text-opacity:1;color:rgba(28,30,33,var(--un-text-opacity));}.blur{--un-blur:blur(8px);filter:var(--un-blur) var(--un-brightness) var(--un-contrast) var(--un-drop-shadow) var(--un-grayscale) var(--un-hue-rotate) var(--un-invert) var(--un-saturate) var(--un-sepia);}.transition-colors-250{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:250ms;}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms;}@media (max-width: 639.9px){.lt-sm\:absolute{position:absolute;}.lt-sm\:z-1999{z-index:1999;}.lt-sm\:h-screen{height:100vh;}.lt-sm\:flex{display:flex;}.lt-sm\:shadow{--un-shadow:var(--un-shadow-inset) 0 1px 3px 0 var(--un-shadow-color, rgba(0,0,0,0.1)),var(--un-shadow-inset) 0 1px 2px -1px var(--un-shadow-color, rgba(0,0,0,0.1));box-shadow:var(--un-ring-offset-shadow, 0 0 #0000), var(--un-ring-shadow, 0 0 #0000), var(--un-shadow);}.lt-sm\:shadow-lg{--un-shadow:var(--un-shadow-inset) 0 10px 15px -3px var(--un-shadow-color, rgba(0,0,0,0.1)),var(--un-shadow-inset) 0 4px 6px -4px var(--un-shadow-color, rgba(0,0,0,0.1));box-shadow:var(--un-ring-offset-shadow, 0 0 #0000), var(--un-ring-shadow, 0 0 #0000), var(--un-shadow);}.lt-sm\:transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms;}}*:not(h1,h2,h3,h4,h5,h6){margin:0;padding:0}*{box-sizing:border-box;font-family:Rubik,sans-serif}::-webkit-scrollbar{width:.25rem;height:3px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{border-radius:.25rem}code{padding:.05rem .25rem}code.code-block{padding:.5rem}#sidebar{width:18.75rem}@media screen and (max-width: 640px){#sidebar{--translate-x: -18.75rem;transform:translate(var(--translate-x))}} +*,::before,::after{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x:var(--un-empty,/*!*/ /*!*/);--un-pan-y:var(--un-empty,/*!*/ /*!*/);--un-pinch-zoom:var(--un-empty,/*!*/ /*!*/);--un-scroll-snap-strictness:proximity;--un-ordinal:var(--un-empty,/*!*/ /*!*/);--un-slashed-zero:var(--un-empty,/*!*/ /*!*/);--un-numeric-figure:var(--un-empty,/*!*/ /*!*/);--un-numeric-spacing:var(--un-empty,/*!*/ /*!*/);--un-numeric-fraction:var(--un-empty,/*!*/ /*!*/);--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 #0000;--un-ring-shadow:0 0 #0000;--un-shadow-inset:var(--un-empty,/*!*/ /*!*/);--un-shadow:0 0 #0000;--un-ring-inset:var(--un-empty,/*!*/ /*!*/);--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgba(147,197,253,0.5);--un-blur:var(--un-empty,/*!*/ /*!*/);--un-brightness:var(--un-empty,/*!*/ /*!*/);--un-contrast:var(--un-empty,/*!*/ /*!*/);--un-drop-shadow:var(--un-empty,/*!*/ /*!*/);--un-grayscale:var(--un-empty,/*!*/ /*!*/);--un-hue-rotate:var(--un-empty,/*!*/ /*!*/);--un-invert:var(--un-empty,/*!*/ /*!*/);--un-saturate:var(--un-empty,/*!*/ /*!*/);--un-sepia:var(--un-empty,/*!*/ /*!*/);--un-backdrop-blur:var(--un-empty,/*!*/ /*!*/);--un-backdrop-brightness:var(--un-empty,/*!*/ /*!*/);--un-backdrop-contrast:var(--un-empty,/*!*/ /*!*/);--un-backdrop-grayscale:var(--un-empty,/*!*/ /*!*/);--un-backdrop-hue-rotate:var(--un-empty,/*!*/ /*!*/);--un-backdrop-invert:var(--un-empty,/*!*/ /*!*/);--un-backdrop-opacity:var(--un-empty,/*!*/ /*!*/);--un-backdrop-saturate:var(--un-empty,/*!*/ /*!*/);--un-backdrop-sepia:var(--un-empty,/*!*/ /*!*/);}@font-face { font-family: 'Fira Code'; font-style: normal; font-weight: 400; font-display: swap; src: url(https://fonts.gstatic.com/s/firacode/v22/uU9eCBsR6Z2vfE9aq3bL0fxyUs4tcw4W_D1sFVc.ttf) format('truetype');}@font-face { font-family: 'Fira Mono'; font-style: normal; font-weight: 400; font-display: swap; src: url(https://fonts.gstatic.com/s/firamono/v14/N0bX2SlFPv1weGeLZDtQIQ.ttf) format('truetype');}@font-face { font-family: 'Fira Mono'; font-style: normal; font-weight: 700; font-display: swap; src: url(https://fonts.gstatic.com/s/firamono/v14/N0bS2SlFPv1weGeLZDtondv3mQ.ttf) format('truetype');}@font-face { font-family: 'Rubik'; font-style: normal; font-weight: 400; font-display: swap; src: url(https://fonts.gstatic.com/s/rubik/v28/iJWZBXyIfDnIV5PNhY1KTN7Z-Yh-B4i1UA.ttf) format('truetype');}.i-codicon-clear-all{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 16 16' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='m10 12.6l.7.7l1.6-1.6l1.6 1.6l.8-.7L13 11l1.7-1.6l-.8-.8l-1.6 1.7l-1.6-1.7l-.7.8l1.6 1.6l-1.6 1.6zM1 4h14V3H1v1zm0 3h14V6H1v1zm8 2.5V9H1v1h8v-.5zM9 13v-1H1v1h8z'/%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-codicon-close{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 16 16' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' fill-rule='evenodd' d='m8 8.707l3.646 3.647l.708-.707L8.707 8l3.647-3.646l-.707-.708L8 7.293L4.354 3.646l-.707.708L7.293 8l-3.646 3.646l.707.708L8 8.707z' clip-rule='evenodd'/%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-codicon-hubot{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 16 16' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' fill-rule='evenodd' d='M8.48 4h4l.5.5v2.03h.52l.5.5V8l-.5.5h-.52v3l-.5.5H9.36l-2.5 2.76L6 14.4V12H3.5l-.5-.64V8.5h-.5L2 8v-.97l.5-.5H3V4.36L3.53 4h4V2.86A1 1 0 0 1 7 2a1 1 0 0 1 2 0a1 1 0 0 1-.52.83V4zM12 8V5H4v5.86l2.5.14H7v2.19l1.8-2.04l.35-.15H12V8zm-2.12.51a2.71 2.71 0 0 1-1.37.74v-.01a2.71 2.71 0 0 1-2.42-.74l-.7.71c.34.34.745.608 1.19.79c.45.188.932.286 1.42.29a3.7 3.7 0 0 0 2.58-1.07l-.7-.71zM6.49 6.5h-1v1h1v-1zm3 0h1v1h-1v-1z' clip-rule='evenodd'/%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-codicon-link-external{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 16 16' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M1.5 1H6v1H2v12h12v-4h1v4.5l-.5.5h-13l-.5-.5v-13l.5-.5z'/%3E%3Cpath d='M15 1.5V8h-1V2.707L7.243 9.465l-.707-.708L13.293 2H8V1h6.5l.5.5z'/%3E%3C/g%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-codicon-menu{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 16 16' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M16 5H0V4h16v1zm0 8H0v-1h16v1zm0-4.008H0V8h16v.992z'/%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-codicon-radio-tower{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 16 16' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' fill-rule='evenodd' d='M2.998 5.58a5.55 5.55 0 0 1 1.62-3.88l-.71-.7a6.45 6.45 0 0 0 0 9.16l.71-.7a5.55 5.55 0 0 1-1.62-3.88zm1.06 0a4.42 4.42 0 0 0 1.32 3.17l.71-.71a3.27 3.27 0 0 1-.76-1.12a3.45 3.45 0 0 1 0-2.67a3.22 3.22 0 0 1 .76-1.13l-.71-.71a4.46 4.46 0 0 0-1.32 3.17zm7.65 3.21l-.71-.71c.33-.32.59-.704.76-1.13a3.449 3.449 0 0 0 0-2.67a3.22 3.22 0 0 0-.76-1.13l.71-.7a4.468 4.468 0 0 1 0 6.34zM13.068 1l-.71.71a5.43 5.43 0 0 1 0 7.74l.71.71a6.45 6.45 0 0 0 0-9.16zM9.993 5.43a1.5 1.5 0 0 1-.245.98a2 2 0 0 1-.27.23l3.44 7.73l-.92.4l-.77-1.73h-5.54l-.77 1.73l-.92-.4l3.44-7.73a1.52 1.52 0 0 1-.33-1.63a1.55 1.55 0 0 1 .56-.68a1.5 1.5 0 0 1 2.325 1.1zm-1.595-.34a.52.52 0 0 0-.25.14a.52.52 0 0 0-.11.22a.48.48 0 0 0 0 .29c.04.09.102.17.18.23a.54.54 0 0 0 .28.08a.51.51 0 0 0 .5-.5a.54.54 0 0 0-.08-.28a.58.58 0 0 0-.23-.18a.48.48 0 0 0-.29 0zm.23 2.05h-.27l-.87 1.94h2l-.86-1.94zm2.2 4.94l-.89-2h-2.88l-.89 2h4.66z' clip-rule='evenodd'/%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-codicon-window{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 16 16' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M14.5 2h-13l-.5.5v11l.5.5h13l.5-.5v-11l-.5-.5zM14 13H2V6h12v7zm0-8H2V3h12v2z'/%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-ph-broadcast{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M128 88a40 40 0 1 0 40 40a40 40 0 0 0-40-40Zm0 64a24 24 0 1 1 24-24a24 24 0 0 1-24 24Zm73.71 7.14a80 80 0 0 1-14.08 22.2a8 8 0 0 1-11.92-10.67a63.95 63.95 0 0 0 0-85.33a8 8 0 1 1 11.92-10.67a80.08 80.08 0 0 1 14.08 84.47ZM69 103.09a64 64 0 0 0 11.26 67.58a8 8 0 0 1-11.92 10.67a79.93 79.93 0 0 1 0-106.67a8 8 0 1 1 11.95 10.67A63.77 63.77 0 0 0 69 103.09ZM248 128a119.58 119.58 0 0 1-34.29 84a8 8 0 1 1-11.42-11.2a103.9 103.9 0 0 0 0-145.56A8 8 0 1 1 213.71 44A119.58 119.58 0 0 1 248 128ZM53.71 200.78A8 8 0 1 1 42.29 212a119.87 119.87 0 0 1 0-168a8 8 0 1 1 11.42 11.2a103.9 103.9 0 0 0 0 145.56Z'/%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-ph-chat-teardrop-text{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M168 112a8 8 0 0 1-8 8H96a8 8 0 0 1 0-16h64a8 8 0 0 1 8 8Zm-8 24H96a8 8 0 0 0 0 16h64a8 8 0 0 0 0-16Zm72-12a100.11 100.11 0 0 1-100 100H47.67A15.69 15.69 0 0 1 32 208.33V124a100 100 0 0 1 200 0Zm-16 0a84 84 0 0 0-168 0v84h84a84.09 84.09 0 0 0 84-84Z'/%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-ph-check-duotone{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M232 56v144a16 16 0 0 1-16 16H40a16 16 0 0 1-16-16V56a16 16 0 0 1 16-16h176a16 16 0 0 1 16 16Z' opacity='.2'/%3E%3Cpath d='m205.66 85.66l-96 96a8 8 0 0 1-11.32 0l-40-40a8 8 0 0 1 11.32-11.32L104 164.69l90.34-90.35a8 8 0 0 1 11.32 11.32Z'/%3E%3C/g%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-ph-globe-stand{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M128 176a80 80 0 1 0-80-80a80.09 80.09 0 0 0 80 80Zm0-144a64 64 0 1 1-64 64a64.07 64.07 0 0 1 64-64Zm77.77 133.5a8 8 0 0 1-.23 11.32a111.24 111.24 0 0 1-69.54 30.9V224h24a8 8 0 0 1 0 16H96a8 8 0 0 1 0-16h24v-16.29A112 112 0 0 1 47.18 18.46a8 8 0 1 1 11.54 11.08a96 96 0 0 0 135.74 135.74a8 8 0 0 1 11.31.22Z'/%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-ph-hand-waving{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='m220.2 100l-18-31.18a28 28 0 0 0-47.3-1.92l-15.34-26.59a28 28 0 0 0-48.12-.63a28 28 0 0 0-43 34.78l3.34 5.79a28 28 0 0 0-22 41.92l38 65.82a87.46 87.46 0 0 0 53.43 41a88.56 88.56 0 0 0 22.92 3A88 88 0 0 0 220.2 100Zm-6.67 62.63A72 72 0 0 1 81.63 180l-38-65.82a12 12 0 0 1 20.79-12l22 38.1a8 8 0 1 0 13.85-8l-38-65.81a12 12 0 0 1 13.5-17.59a11.9 11.9 0 0 1 7.29 5.59l34 58.89a8 8 0 0 0 13.85-8l-26-45a12 12 0 0 1 20.78-12L160 107.78a48.08 48.08 0 0 0-11 61a8 8 0 0 0 13.86-8a32 32 0 0 1 11.71-43.71a8 8 0 0 0 2.93-10.93l-10-17.32a12 12 0 0 1 20.78-12l18 31.18a71.49 71.49 0 0 1 7.25 54.62Zm-29.26-132.7a8 8 0 0 1 9.8-5.66c15.91 4.27 29 14.11 36.86 27.73a8 8 0 0 1-13.86 8c-5.72-9.92-15.36-17.12-27.14-20.27a8 8 0 0 1-5.66-9.8ZM80.91 237a8 8 0 0 1-11.24 1.33c-11-8.69-20.11-19.58-28.6-34.28a8 8 0 0 1 13.86-8c7.44 12.88 15.27 22.32 24.65 29.72A8 8 0 0 1 80.91 237Z'/%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-ph-images-square{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M208 32H80a16 16 0 0 0-16 16v16H48a16 16 0 0 0-16 16v128a16 16 0 0 0 16 16h128a16 16 0 0 0 16-16v-16h16a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16ZM80 48h128v69.38l-16.7-16.7a16 16 0 0 0-22.62 0L93.37 176H80Zm96 160H48V80h16v96a16 16 0 0 0 16 16h96Zm32-32h-92l64-64l28 28v36Zm-88-64a24 24 0 1 0-24-24a24 24 0 0 0 24 24Zm0-32a8 8 0 1 1-8 8a8 8 0 0 1 8-8Z'/%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-ph-list{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M224 128a8 8 0 0 1-8 8H40a8 8 0 0 1 0-16h176a8 8 0 0 1 8 8ZM40 72h176a8 8 0 0 0 0-16H40a8 8 0 0 0 0 16Zm176 112H40a8 8 0 0 0 0 16h176a8 8 0 0 0 0-16Z'/%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-ph-moon{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M233.54 142.23a8 8 0 0 0-8-2a88.08 88.08 0 0 1-109.8-109.8a8 8 0 0 0-10-10a104.84 104.84 0 0 0-52.91 37A104 104 0 0 0 136 224a103.09 103.09 0 0 0 62.52-20.88a104.84 104.84 0 0 0 37-52.91a8 8 0 0 0-1.98-7.98Zm-44.64 48.11A88 88 0 0 1 65.66 67.11a89 89 0 0 1 31.4-26A106 106 0 0 0 96 56a104.11 104.11 0 0 0 104 104a106 106 0 0 0 14.92-1.06a89 89 0 0 1-26.02 31.4Z'/%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-ph-square-duotone{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M216 48v160a8 8 0 0 1-8 8H48a8 8 0 0 1-8-8V48a8 8 0 0 1 8-8h160a8 8 0 0 1 8 8Z' opacity='.2'/%3E%3Cpath d='M208 32H48a16 16 0 0 0-16 16v160a16 16 0 0 0 16 16h160a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16Zm0 176H48V48h160v160Z'/%3E%3C/g%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-ph-sun{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M120 40V16a8 8 0 0 1 16 0v24a8 8 0 0 1-16 0Zm72 88a64 64 0 1 1-64-64a64.07 64.07 0 0 1 64 64Zm-16 0a48 48 0 1 0-48 48a48.05 48.05 0 0 0 48-48ZM58.34 69.66a8 8 0 0 0 11.32-11.32l-16-16a8 8 0 0 0-11.32 11.32Zm0 116.68l-16 16a8 8 0 0 0 11.32 11.32l16-16a8 8 0 0 0-11.32-11.32ZM192 72a8 8 0 0 0 5.66-2.34l16-16a8 8 0 0 0-11.32-11.32l-16 16A8 8 0 0 0 192 72Zm5.66 114.34a8 8 0 0 0-11.32 11.32l16 16a8 8 0 0 0 11.32-11.32ZM48 128a8 8 0 0 0-8-8H16a8 8 0 0 0 0 16h24a8 8 0 0 0 8-8Zm80 80a8 8 0 0 0-8 8v24a8 8 0 0 0 16 0v-24a8 8 0 0 0-8-8Zm112-88h-24a8 8 0 0 0 0 16h24a8 8 0 0 0 0-16Z'/%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.i-ph-tray{--un-icon:url("data:image/svg+xml;utf8,%3Csvg preserveAspectRatio='xMidYMid meet' viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M208 32H48a16 16 0 0 0-16 16v160a16 16 0 0 0 16 16h160a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16Zm0 16v104h-28.7a15.86 15.86 0 0 0-11.3 4.69L148.69 176h-41.38L88 156.69A15.86 15.86 0 0 0 76.69 152H48V48Zm0 160H48v-40h28.69L96 187.31a15.86 15.86 0 0 0 11.31 4.69h41.38a15.86 15.86 0 0 0 11.31-4.69L179.31 168H208v40Z'/%3E%3C/svg%3E");mask:var(--un-icon) no-repeat;mask-size:100% 100%;-webkit-mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;}.note-red{position:relative;display:inline-flex;align-items:center;border-left-width:4px;border-left-style:solid;--un-border-opacity:1;border-color:rgba(53,120,229,var(--un-border-opacity));border-radius:0.25rem;background-color:rgba(53,120,229,0.1);background-color:rgba(185,28,28,0.1);padding:0.5rem;text-decoration:none;}.nv{position:relative;display:flex;align-items:center;border-radius:0.25rem;padding:0.5rem;--un-text-opacity:1;color:rgba(194,197,202,var(--un-text-opacity));text-decoration:none;transition-property:all;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:125ms;}.nv_selected{position:relative;display:flex;align-items:center;border-left-width:4px;border-left-style:solid;border-radius:0.25rem;--un-bg-opacity:.05;background-color:hsla(0,0%,100%,var(--un-bg-opacity));padding:0.5rem;--un-text-opacity:1;color:rgba(194,197,202,var(--un-text-opacity));color:rgba(53,120,229,var(--un-text-opacity));text-decoration:none;transition-property:all;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:125ms;}.input{height:2.5rem;display:flex;align-items:center;border-radius:0.25rem;border-style:none;--un-bg-opacity:1;background-color:rgba(233,236,239,var(--un-bg-opacity));padding:0.5rem;--un-text-opacity:1;color:rgba(28,30,33,var(--un-text-opacity));--un-shadow:var(--un-shadow-inset) 0 4px 6px -1px var(--un-shadow-color, rgba(0,0,0,0.1)),var(--un-shadow-inset) 0 2px 4px -2px var(--un-shadow-color, rgba(0,0,0,0.1));box-shadow:var(--un-ring-offset-shadow, 0 0 #0000), var(--un-ring-shadow, 0 0 #0000), var(--un-shadow);outline:2px solid transparent;outline-offset:2px;}.btn{user-select:none;border-radius:0.25rem;border-style:none;--un-bg-opacity:1;background-color:rgba(53,120,229,var(--un-bg-opacity));padding:0.5rem;font-weight:400;--un-text-opacity:1;color:rgba(28,30,33,var(--un-text-opacity));color:rgba(255,255,255,var(--un-text-opacity));--un-shadow:var(--un-shadow-inset) 0 4px 6px -1px var(--un-shadow-color, rgba(0,0,0,0.1)),var(--un-shadow-inset) 0 2px 4px -2px var(--un-shadow-color, rgba(0,0,0,0.1));box-shadow:var(--un-ring-offset-shadow, 0 0 #0000), var(--un-ring-shadow, 0 0 #0000), var(--un-shadow);outline:2px solid transparent;outline-offset:2px;}.nv_selected:hover,.nv:hover{border-left-width:4px;border-left-style:solid;--un-bg-opacity:.05;background-color:hsla(0,0%,100%,var(--un-bg-opacity));--un-text-opacity:1;color:rgba(53,120,229,var(--un-text-opacity));}.dark .note-red{--un-border-opacity:1;border-color:rgba(103,214,237,var(--un-border-opacity));background-color:rgba(103,214,237,0.1);background-color:rgba(185,28,28,0.1);}.btn:hover{--un-bg-opacity:1;background-color:rgba(45,102,195,var(--un-bg-opacity));}.dark .btn{--un-bg-opacity:1;background-color:rgba(103,214,237,var(--un-bg-opacity));font-weight:600;--un-text-opacity:1;color:rgba(28,30,33,var(--un-text-opacity));}.dark .btn:hover{--un-bg-opacity:1;background-color:rgba(57,202,232,var(--un-bg-opacity));}.dark .input{--un-bg-opacity:1;background-color:rgba(36,37,38,var(--un-bg-opacity));--un-text-opacity:1;color:rgba(227,227,227,var(--un-text-opacity));}.dark .note-red::after,.note-red::after{--un-bg-opacity:1;background-color:rgba(185,28,28,var(--un-bg-opacity));}.btn:active{--un-bg-opacity:1;background-color:rgba(37,84,160,var(--un-bg-opacity));}.dark .btn:active{--un-bg-opacity:1;background-color:rgba(25,181,213,var(--un-bg-opacity));}.dark .nv_selected,.dark .nv_selected:hover,.dark .nv:hover{--un-text-opacity:1;color:rgba(103,214,237,var(--un-text-opacity));} ::-webkit-scrollbar-thumb { background-color: #3578E5; } .dark ::-webkit-scrollbar-thumb { background-color: #67d6ed; } code { font-size: 0.75rem; font-family: "Fira Code","Fira Mono",ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; border-radius: 0.25rem; background-color: #d6d8da; } .code-block { font-family: "Fira Code","Fira Mono",ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; font-size: 0.875rem; } .dark code { background-color: #282a2e; } .visible{visibility:visible;}.absolute{position:absolute;}.left-2{left:0.5rem;}.top-2{top:0.5rem;}.z-2000{z-index:2000;}.grid{display:grid;}.grid-rows-\[2fr_auto\]{grid-template-rows:2fr auto;}.grid-rows-\[2px_2rem_1fr\]{grid-template-rows:2px 2rem 1fr;}.grid-rows-\[auto_1fr\]{grid-template-rows:auto 1fr;}.grid-rows-\[min-content_auto\]{grid-template-rows:min-content auto;}.mb-2{margin-bottom:0.5rem;}.mr-2{margin-right:0.5rem;}.display-none{display:none;}.children-h-10>*{height:2.5rem;}.h-15rem{height:15rem;}.h-2px{height:2px;}.h-8{height:2rem;}.h-85\%{height:85%;}.h-screen{height:100vh;}.w-1px{width:1px;}.w-8{width:2rem;}.w-screen{width:100vw;}.flex{display:flex;}.flex-1{flex:1 1 0%;}.children-flex-none>*{flex:none;}.flex-shrink-0{flex-shrink:0;}.children\:grow>*,.grow{flex-grow:1;}.flex-grow-0{flex-grow:0;}.flex-row{flex-direction:row;}.flex-col{flex-direction:column;}.flex-wrap{flex-wrap:wrap;}@keyframes fade-in{from{opacity:0}to{opacity:1}}.animate-fade-in{animation:fade-in 1s linear 1;}.animate-duration-300ms{animation-duration:300ms;}.cursor-ns-resize{cursor:ns-resize;}.cursor-pointer{cursor:pointer;}.select-none{user-select:none;}.items-center{align-items:center;}.self-center{align-self:center;}.justify-center{justify-content:center;}.justify-between{justify-content:space-between;}.gap-1{grid-gap:0.25rem;gap:0.25rem;}.gap-2{grid-gap:0.5rem;gap:0.5rem;}.overflow-hidden{overflow:hidden;}.overflow-y-auto{overflow-y:auto;}.b{border-width:1px;border-style:solid;}.rd-1{border-radius:0.25rem;}.rd-8{border-radius:2rem;}.bg-accent{--un-bg-opacity:1;background-color:rgba(53,120,229,var(--un-bg-opacity));}.bg-black\/20{background-color:rgba(0,0,0,0.2);}.bg-darkPrimaryLighter{--un-bg-opacity:1;background-color:rgba(36,37,38,var(--un-bg-opacity));}.bg-gray\/30{background-color:rgba(156,163,175,0.3);}.bg-primary{--un-bg-opacity:1;background-color:rgba(255,255,255,var(--un-bg-opacity));}.bg-white\/5,.dark .dark\:bg-white\/5{background-color:rgba(255,255,255,0.05);}.dark .dark\:bg-darkAccent{--un-bg-opacity:1;background-color:rgba(103,214,237,var(--un-bg-opacity));}.dark .dark\:bg-darkPrimary{--un-bg-opacity:1;background-color:rgba(27,27,29,var(--un-bg-opacity));}.dark .dark\:hover\:bg-darkHoverOverlay:hover{--un-bg-opacity:.05;background-color:hsla(0,0%,100%,var(--un-bg-opacity));}.hover\:bg-hoverOverlay:hover{--un-bg-opacity:.05;background-color:rgba(0,0,0,var(--un-bg-opacity));}.active\:bg-accentDark:active{--un-bg-opacity:1;background-color:rgba(48,108,206,var(--un-bg-opacity));}.active\:bg-hoverOverlay\/25:active{background-color:rgba(0,0,0,0.25);}.dark .dark\:active\:bg-darkAccentDark:active{--un-bg-opacity:1;background-color:rgba(73,206,233,var(--un-bg-opacity));}.dark .dark\:active\:bg-darkHoverOverlay\/25:active{background-color:hsla(0,0%,100%,0.25);}.p-1{padding:0.25rem;}.p-7{padding:1.75rem;}.px{padding-left:1rem;padding-right:1rem;}.px-2{padding-left:0.5rem;padding-right:0.5rem;}.px-5{padding-left:1.25rem;padding-right:1.25rem;}.children-pb-2>*{padding-bottom:0.5rem;}.children-pt8>*{padding-top:2rem;}.all\:font-mono *{font-family:"Fira Code","Fira Mono",ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;}.all\:text-xs *{font-size:0.75rem;line-height:1rem;}.text-sm{font-size:0.875rem;line-height:1.25rem;}.font-700{font-weight:700;}.font-semibold{font-weight:600;}.dark .dark\:text-darkAccent{--un-text-opacity:1;color:rgba(103,214,237,var(--un-text-opacity));}.dark .dark\:text-darkPrimaryText{--un-text-opacity:1;color:rgba(227,227,227,var(--un-text-opacity));}.text-accent{--un-text-opacity:1;color:rgba(53,120,229,var(--un-text-opacity));}.text-primaryText{--un-text-opacity:1;color:rgba(28,30,33,var(--un-text-opacity));}.blur{--un-blur:blur(8px);filter:var(--un-blur) var(--un-brightness) var(--un-contrast) var(--un-drop-shadow) var(--un-grayscale) var(--un-hue-rotate) var(--un-invert) var(--un-saturate) var(--un-sepia);}.transition-colors-250{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:250ms;}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms;}@media (max-width: 639.9px){.lt-sm\:absolute{position:absolute;}.lt-sm\:z-1999{z-index:1999;}.lt-sm\:h-screen{height:100vh;}.lt-sm\:flex{display:flex;}.lt-sm\:shadow{--un-shadow:var(--un-shadow-inset) 0 1px 3px 0 var(--un-shadow-color, rgba(0,0,0,0.1)),var(--un-shadow-inset) 0 1px 2px -1px var(--un-shadow-color, rgba(0,0,0,0.1));box-shadow:var(--un-ring-offset-shadow, 0 0 #0000), var(--un-ring-shadow, 0 0 #0000), var(--un-shadow);}.lt-sm\:shadow-lg{--un-shadow:var(--un-shadow-inset) 0 10px 15px -3px var(--un-shadow-color, rgba(0,0,0,0.1)),var(--un-shadow-inset) 0 4px 6px -4px var(--un-shadow-color, rgba(0,0,0,0.1));box-shadow:var(--un-ring-offset-shadow, 0 0 #0000), var(--un-ring-shadow, 0 0 #0000), var(--un-shadow);}.lt-sm\:transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms;}}*:not(h1,h2,h3,h4,h5,h6){margin:0;padding:0}*{box-sizing:border-box;font-family:Rubik,sans-serif}::-webkit-scrollbar{width:.25rem;height:3px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{border-radius:.25rem}code{padding:.05rem .25rem}code.code-block{padding:.5rem}#sidebar{width:18.75rem}@media screen and (max-width: 640px){#sidebar{--translate-x: -18.75rem;transform:translate(var(--translate-x))}} diff --git a/examples/api/dist/assets/index.js b/examples/api/dist/assets/index.js index 88acdd8fca5..5c6ee7bdb46 100644 --- a/examples/api/dist/assets/index.js +++ b/examples/api/dist/assets/index.js @@ -1,41 +1,43 @@ -var Rs=Object.defineProperty;var Hs=(e,t,n)=>t in e?Rs(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var ft=(e,t,n)=>(Hs(e,typeof t!="symbol"?t+"":t,n),n);(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))i(o);new MutationObserver(o=>{for(const r of o)if(r.type==="childList")for(const g of r.addedNodes)g.tagName==="LINK"&&g.rel==="modulepreload"&&i(g)}).observe(document,{childList:!0,subtree:!0});function n(o){const r={};return o.integrity&&(r.integrity=o.integrity),o.referrerPolicy&&(r.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?r.credentials="include":o.crossOrigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function i(o){if(o.ep)return;o.ep=!0;const r=n(o);fetch(o.href,r)}})();function ee(){}function Es(e){return e()}function is(){return Object.create(null)}function je(e){e.forEach(Es)}function Is(e){return typeof e=="function"}function Ot(e,t){return e!=e?t==t:e!==t||e&&typeof e=="object"||typeof e=="function"}let Sl;function Fs(e,t){return e===t?!0:(Sl||(Sl=document.createElement("a")),Sl.href=t,e===Sl.href)}function Us(e){return Object.keys(e).length===0}function qs(e,...t){if(e==null){for(const i of t)i(void 0);return ee}const n=e.subscribe(...t);return n.unsubscribe?()=>n.unsubscribe():n}function Bs(e,t,n){e.$$.on_destroy.push(qs(t,n))}function l(e,t){e.appendChild(t)}function w(e,t,n){e.insertBefore(t,n||null)}function m(e){e.parentNode&&e.parentNode.removeChild(e)}function Pt(e,t){for(let n=0;ne.removeEventListener(t,n,i)}function ss(e){return function(t){return t.preventDefault(),e.call(this,t)}}function a(e,t,n){n==null?e.removeAttribute(t):e.getAttribute(t)!==n&&e.setAttribute(t,n)}function q(e){return e===""?null:+e}function Vs(e){return Array.from(e.childNodes)}function se(e,t){t=""+t,e.data!==t&&(e.data=t)}function E(e,t){e.value=t??""}function Qt(e,t,n,i){n==null?e.style.removeProperty(t):e.style.setProperty(t,n,i?"important":"")}function Ke(e,t,n){for(let i=0;ie.indexOf(i)===-1?t.push(i):n.push(i)),n.forEach(i=>i()),$t=t}const zl=new Set;let St;function Zs(){St={r:0,c:[],p:St}}function Js(){St.r||je(St.c),St=St.p}function ri(e,t){e&&e.i&&(zl.delete(e),e.i(t))}function rs(e,t,n,i){if(e&&e.o){if(zl.has(e))return;zl.add(e),St.c.push(()=>{zl.delete(e),i&&(n&&e.d(1),i())}),e.o(t)}else i&&i()}function ye(e){return(e==null?void 0:e.length)!==void 0?e:Array.from(e)}function us(e){e&&e.c()}function ui(e,t,n){const{fragment:i,after_update:o}=e.$$;i&&i.m(t,n),ht(()=>{const r=e.$$.on_mount.map(Es).filter(Is);e.$$.on_destroy?e.$$.on_destroy.push(...r):je(r),e.$$.on_mount=[]}),o.forEach(ht)}function ci(e,t){const n=e.$$;n.fragment!==null&&(Qs(n.after_update),je(n.on_destroy),n.fragment&&n.fragment.d(t),n.on_destroy=n.fragment=null,n.ctx=[])}function xs(e,t){e.$$.dirty[0]===-1&&(xt.push(e),Ys(),e.$$.dirty.fill(0)),e.$$.dirty[t/31|0]|=1<{const I=S.length?S[0]:Y;return d.ctx&&o(d.ctx[L],d.ctx[L]=I)&&(!d.skip_bound&&d.bound[L]&&d.bound[L](I),W&&xs(e,L)),Y}):[],d.update(),W=!0,je(d.before_update),d.fragment=i?i(d.ctx):!1,t.target){if(t.hydrate){const L=Vs(t.target);d.fragment&&d.fragment.l(L),L.forEach(m)}else d.fragment&&d.fragment.c();t.intro&&ri(e.$$.fragment),ui(e,t.target,t.anchor),As()}kn(b)}class nn{constructor(){ft(this,"$$");ft(this,"$$set")}$destroy(){ci(this,1),this.$destroy=ee}$on(t,n){if(!Is(n))return ee;const i=this.$$.callbacks[t]||(this.$$.callbacks[t]=[]);return i.push(n),()=>{const o=i.indexOf(n);o!==-1&&i.splice(o,1)}}$set(t){this.$$set&&!Us(t)&&(this.$$.skip_bound=!0,this.$$set(t),this.$$.skip_bound=!1)}}const $s="4";typeof window<"u"&&(window.__svelte||(window.__svelte={v:new Set})).v.add($s);const Jt=[];function eo(e,t=ee){let n;const i=new Set;function o(h){if(Ot(e,h)&&(e=h,n)){const b=!Jt.length;for(const d of i)d[1](),Jt.push(d,e);if(b){for(let d=0;d{i.delete(d),i.size===0&&n&&(n(),n=null)}}return{set:o,update:r,subscribe:g}}function to(e,t=!1){return window.__TAURI_INTERNALS__.transformCallback(e,t)}async function _(e,t={},n){return window.__TAURI_INTERNALS__.invoke(e,t,n)}async function no(){return _("plugin:app|version")}async function lo(){return _("plugin:app|name")}async function io(){return _("plugin:app|tauri_version")}async function so(){return _("plugin:app|app_show")}async function oo(){return _("plugin:app|app_hide")}function ao(e){let t,n,i,o,r,g,h,b,d,W,L,Y,S,I,M,D,ae,H,N,V,G,O,B,re;return{c(){t=s("div"),n=s("p"),n.innerHTML=`This is a demo of Tauri's API capabilities using the @tauri-apps/api package. It's used as the main validation app, serving as the test bed of our +var wr=Object.defineProperty;var kr=(t,e,n)=>e in t?wr(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var _t=(t,e,n)=>(kr(t,typeof e!="symbol"?e+"":e,n),n);(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))l(s);new MutationObserver(s=>{for(const u of s)if(u.type==="childList")for(const d of u.addedNodes)d.tagName==="LINK"&&d.rel==="modulepreload"&&l(d)}).observe(document,{childList:!0,subtree:!0});function n(s){const u={};return s.integrity&&(u.integrity=s.integrity),s.referrerPolicy&&(u.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?u.credentials="include":s.crossOrigin==="anonymous"?u.credentials="omit":u.credentials="same-origin",u}function l(s){if(s.ep)return;s.ep=!0;const u=n(s);fetch(s.href,u)}})();function ne(){}function $s(t){return t()}function ys(){return Object.create(null)}function Ce(t){t.forEach($s)}function xs(t){return typeof t=="function"}function je(t,e){return t!=t?e==e:t!==e||t&&typeof t=="object"||typeof t=="function"}let Di;function yr(t,e){return t===e?!0:(Di||(Di=document.createElement("a")),Di.href=e,t===Di.href)}function vr(t){return Object.keys(t).length===0}function Cr(t,...e){if(t==null){for(const l of e)l(void 0);return ne}const n=t.subscribe(...e);return n.unsubscribe?()=>n.unsubscribe():n}function Sr(t,e,n){t.$$.on_destroy.push(Cr(e,n))}function i(t,e){t.appendChild(e)}function S(t,e,n){t.insertBefore(e,n||null)}function C(t){t.parentNode&&t.parentNode.removeChild(t)}function Je(t,e){for(let n=0;nt.removeEventListener(e,n,l)}function vs(t){return function(e){return e.preventDefault(),t.call(this,e)}}function a(t,e,n){n==null?t.removeAttribute(e):t.getAttribute(e)!==n&&t.setAttribute(e,n)}function X(t){return t===""?null:+t}function Lr(t){return Array.from(t.childNodes)}function se(t,e){e=""+e,t.data!==e&&(t.data=e)}function z(t,e){t.value=e??""}function $t(t,e,n,l){n==null?t.style.removeProperty(e):t.style.setProperty(e,n,l?"important":"")}function Qe(t,e,n){for(let l=0;l{const s=t.$$.callbacks[e];if(s){const u=Pr(e,n,{cancelable:l});return s.slice().forEach(d=>{d.call(t,u)}),!u.defaultPrevented}return!0}}const tn=[],Tn=[];let nn=[];const Sl=[],Er=Promise.resolve();let Ml=!1;function Ir(){Ml||(Ml=!0,Er.then(ir))}function wt(t){nn.push(t)}function nr(t){Sl.push(t)}const wl=new Set;let xt=0;function ir(){if(xt!==0)return;const t=In;do{try{for(;xtt.indexOf(l)===-1?e.push(l):n.push(l)),n.forEach(l=>l()),nn=e}const Fi=new Set;let Tt;function Or(){Tt={r:0,c:[],p:Tt}}function Wr(){Tt.r||Ce(Tt.c),Tt=Tt.p}function sn(t,e){t&&t.i&&(Fi.delete(t),t.i(e))}function zn(t,e,n,l){if(t&&t.o){if(Fi.has(t))return;Fi.add(t),Tt.c.push(()=>{Fi.delete(t),l&&(n&&t.d(1),l())}),t.o(e)}else l&&l()}function he(t){return(t==null?void 0:t.length)!==void 0?t:Array.from(t)}function lr(t,e,n){const l=t.$$.props[e];l!==void 0&&(t.$$.bound[l]=n,n(t.$$.ctx[l]))}function On(t){t&&t.c()}function rn(t,e,n){const{fragment:l,after_update:s}=t.$$;l&&l.m(e,n),wt(()=>{const u=t.$$.on_mount.map($s).filter(xs);t.$$.on_destroy?t.$$.on_destroy.push(...u):Ce(u),t.$$.on_mount=[]}),s.forEach(wt)}function an(t,e){const n=t.$$;n.fragment!==null&&(zr(n.after_update),Ce(n.on_destroy),n.fragment&&n.fragment.d(e),n.on_destroy=n.fragment=null,n.ctx=[])}function Rr(t,e){t.$$.dirty[0]===-1&&(tn.push(t),Ir(),t.$$.dirty.fill(0)),t.$$.dirty[e/31|0]|=1<{const P=_.length?_[0]:O;return h.ctx&&s(h.ctx[b],h.ctx[b]=P)&&(!h.skip_bound&&h.bound[b]&&h.bound[b](P),k&&Rr(t,b)),O}):[],h.update(),k=!0,Ce(h.before_update),h.fragment=l?l(h.ctx):!1,e.target){if(e.hydrate){const b=Lr(e.target);h.fragment&&h.fragment.l(b),b.forEach(C)}else h.fragment&&h.fragment.c();e.intro&&sn(t.$$.fragment),rn(t,e.target,e.anchor),ir()}En(c)}class $e{constructor(){_t(this,"$$");_t(this,"$$set")}$destroy(){an(this,1),this.$destroy=ne}$on(e,n){if(!xs(n))return ne;const l=this.$$.callbacks[e]||(this.$$.callbacks[e]=[]);return l.push(n),()=>{const s=l.indexOf(n);s!==-1&&l.splice(s,1)}}$set(e){this.$$set&&!vr(e)&&(this.$$.skip_bound=!0,this.$$set(e),this.$$.skip_bound=!1)}}const Dr="4";typeof window<"u"&&(window.__svelte||(window.__svelte={v:new Set})).v.add(Dr);const en=[];function Fr(t,e=ne){let n;const l=new Set;function s(o){if(je(t,o)&&(t=o,n)){const c=!en.length;for(const h of l)h[1](),en.push(h,t);if(c){for(let h=0;h{l.delete(h),l.size===0&&n&&(n(),n=null)}}return{set:s,update:u,subscribe:d}}function Wn(t,e,n,l){if(n==="a"&&!l)throw new TypeError("Private accessor was defined without a getter");if(typeof e=="function"?t!==e||!l:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return n==="m"?l:n==="a"?l.call(t):l?l.value:e.get(t)}function qi(t,e,n,l,s){if(l==="m")throw new TypeError("Private method is not writable");if(l==="a"&&!s)throw new TypeError("Private accessor was defined without a setter");if(typeof e=="function"?t!==e||!s:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return l==="a"?s.call(t,n):s?s.value=n:e.set(t,n),n}var An;function sr(t,e=!1){return window.__TAURI_INTERNALS__.transformCallback(t,e)}class rr{constructor(){this.__TAURI_CHANNEL_MARKER__=!0,An.set(this,()=>{}),this.id=sr(e=>{Wn(this,An,"f").call(this,e)})}set onmessage(e){qi(this,An,e,"f")}get onmessage(){return Wn(this,An,"f")}toJSON(){return`__CHANNEL__:${this.id}`}}An=new WeakMap;async function m(t,e={},n){return window.__TAURI_INTERNALS__.invoke(t,e,n)}async function Hr(){return m("plugin:app|version")}async function Ur(){return m("plugin:app|name")}async function Br(){return m("plugin:app|tauri_version")}async function Vr(){return m("plugin:app|app_show")}async function qr(){return m("plugin:app|app_hide")}function Nr(t){let e,n,l,s,u,d,o,c,h,k,b,O,_,P,v,E,V,D,L,W,A,I,R,Y;return{c(){e=r("div"),n=r("p"),n.innerHTML=`This is a demo of Tauri's API capabilities using the @tauri-apps/api package. It's used as the main validation app, serving as the test bed of our development process. In the future, this app will be used on Tauri's integration - tests.`,i=c(),o=s("br"),r=c(),g=s("br"),h=c(),b=s("pre"),d=p(" App name: "),W=s("code"),L=p(e[2]),Y=p(` - App version: `),S=s("code"),I=p(e[0]),M=p(` - Tauri version: `),D=s("code"),ae=p(e[1]),H=p(` - `),N=c(),V=s("br"),G=c(),O=s("button"),O.textContent="Context menu",a(O,"class","btn")},m(T,x){w(T,t,x),l(t,n),l(t,i),l(t,o),l(t,r),l(t,g),l(t,h),l(t,b),l(b,d),l(b,W),l(W,L),l(b,Y),l(b,S),l(S,I),l(b,M),l(b,D),l(D,ae),l(b,H),l(t,N),l(t,V),l(t,G),l(t,O),B||(re=k(O,"click",e[3]),B=!0)},p(T,[x]){x&4&&se(L,T[2]),x&1&&se(I,T[0]),x&2&&se(ae,T[1])},i:ee,o:ee,d(T){T&&m(t),B=!1,re()}}}function ro(e,t,n){let i="1.0.0",o="1.0.0",r="Unknown";lo().then(h=>{n(2,r=h)}),no().then(h=>{n(0,i=h)}),io().then(h=>{n(1,o=h)});function g(){_("popup_context_menu")}return[i,o,r,g]}class uo extends nn{constructor(t){super(),tn(this,t,ro,ao,Ot,{})}}var Se;(function(e){e.WINDOW_RESIZED="tauri://resize",e.WINDOW_MOVED="tauri://move",e.WINDOW_CLOSE_REQUESTED="tauri://close-requested",e.WINDOW_CREATED="tauri://window-created",e.WINDOW_DESTROYED="tauri://destroyed",e.WINDOW_FOCUS="tauri://focus",e.WINDOW_BLUR="tauri://blur",e.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",e.WINDOW_THEME_CHANGED="tauri://theme-changed",e.WINDOW_FILE_DROP="tauri://file-drop",e.WINDOW_FILE_DROP_HOVER="tauri://file-drop-hover",e.WINDOW_FILE_DROP_CANCELLED="tauri://file-drop-cancelled",e.MENU="tauri://menu"})(Se||(Se={}));async function Ds(e,t){await _("plugin:event|unlisten",{event:e,eventId:t})}async function hi(e,t,n){return _("plugin:event|listen",{event:e,windowLabel:n==null?void 0:n.target,handler:to(t)}).then(i=>async()=>Ds(e,i))}async function co(e,t,n){return hi(e,i=>{t(i),Ds(e,i.id).catch(()=>{})},n)}async function Ns(e,t,n){await _("plugin:event|emit",{event:e,windowLabel:n==null?void 0:n.target,payload:t})}function fo(e){let t,n,i,o,r,g,h,b;return{c(){t=s("div"),n=s("button"),n.textContent="Call Log API",i=c(),o=s("button"),o.textContent="Call Request (async) API",r=c(),g=s("button"),g.textContent="Send event to Rust",a(n,"class","btn"),a(n,"id","log"),a(o,"class","btn"),a(o,"id","request"),a(g,"class","btn"),a(g,"id","event")},m(d,W){w(d,t,W),l(t,n),l(t,i),l(t,o),l(t,r),l(t,g),h||(b=[k(n,"click",e[0]),k(o,"click",e[1]),k(g,"click",e[2])],h=!0)},p:ee,i:ee,o:ee,d(d){d&&m(t),h=!1,je(b)}}}function ho(e,t,n){let{onMessage:i}=t,o;Pl(async()=>{o=await hi("rust-event",i)}),Ws(()=>{o&&o()});function r(){_("log_operation",{event:"tauri-click",payload:"this payload is optional because we used Option in Rust"})}function g(){_("perform_request",{endpoint:"dummy endpoint arg",body:{id:5,name:"test"}}).then(i).catch(i)}function h(){Ns("js-event","this is the payload string")}return e.$$set=b=>{"onMessage"in b&&n(3,i=b.onMessage)},[r,g,h,i]}class po extends nn{constructor(t){super(),tn(this,t,ho,fo,Ot,{onMessage:3})}}class di{constructor(t,n){this.type="Logical",this.width=t,this.height=n}}class en{constructor(t,n){this.type="Physical",this.width=t,this.height=n}toLogical(t){return new di(this.width/t,this.height/t)}}class bo{constructor(t,n){this.type="Logical",this.x=t,this.y=n}}class zt{constructor(t,n){this.type="Physical",this.x=t,this.y=n}toLogical(t){return new bo(this.x/t,this.y/t)}}var Ol;(function(e){e[e.Critical=1]="Critical",e[e.Informational=2]="Informational"})(Ol||(Ol={}));class _o{constructor(t){this._preventDefault=!1,this.event=t.event,this.windowLabel=t.windowLabel,this.id=t.id}preventDefault(){this._preventDefault=!0}isPreventDefault(){return this._preventDefault}}var El;(function(e){e.None="none",e.Normal="normal",e.Indeterminate="indeterminate",e.Paused="paused",e.Error="error"})(El||(El={}));function Ts(){return new Cn(window.__TAURI_INTERNALS__.metadata.currentWindow.label,{skip:!0})}function si(){return window.__TAURI_INTERNALS__.metadata.windows.map(e=>new Cn(e.label,{skip:!0}))}const cs=["tauri://created","tauri://error"];class Cn{constructor(t,n={}){this.label=t,this.listeners=Object.create(null),n!=null&&n.skip||_("plugin:window|create",{options:{...n,label:t}}).then(async()=>this.emit("tauri://created")).catch(async i=>this.emit("tauri://error",i))}static getByLabel(t){return si().some(n=>n.label===t)?new Cn(t,{skip:!0}):null}static getCurrent(){return Ts()}static getAll(){return si()}static async getFocusedWindow(){for(const t of si())if(await t.isFocused())return t;return null}async listen(t,n){return this._handleTauriEvent(t,n)?Promise.resolve(()=>{const i=this.listeners[t];i.splice(i.indexOf(n),1)}):hi(t,n,{target:this.label})}async once(t,n){return this._handleTauriEvent(t,n)?Promise.resolve(()=>{const i=this.listeners[t];i.splice(i.indexOf(n),1)}):co(t,n,{target:this.label})}async emit(t,n){if(cs.includes(t)){for(const i of this.listeners[t]||[])i({event:t,id:-1,windowLabel:this.label,payload:n});return Promise.resolve()}return Ns(t,n,{target:this.label})}_handleTauriEvent(t,n){return cs.includes(t)?(t in this.listeners?this.listeners[t].push(n):this.listeners[t]=[n],!0):!1}async scaleFactor(){return _("plugin:window|scale_factor",{label:this.label})}async innerPosition(){return _("plugin:window|inner_position",{label:this.label}).then(({x:t,y:n})=>new zt(t,n))}async outerPosition(){return _("plugin:window|outer_position",{label:this.label}).then(({x:t,y:n})=>new zt(t,n))}async innerSize(){return _("plugin:window|inner_size",{label:this.label}).then(({width:t,height:n})=>new en(t,n))}async outerSize(){return _("plugin:window|outer_size",{label:this.label}).then(({width:t,height:n})=>new en(t,n))}async isFullscreen(){return _("plugin:window|is_fullscreen",{label:this.label})}async isMinimized(){return _("plugin:window|is_minimized",{label:this.label})}async isMaximized(){return _("plugin:window|is_maximized",{label:this.label})}async isFocused(){return _("plugin:window|is_focused",{label:this.label})}async isDecorated(){return _("plugin:window|is_decorated",{label:this.label})}async isResizable(){return _("plugin:window|is_resizable",{label:this.label})}async isMaximizable(){return _("plugin:window|is_maximizable",{label:this.label})}async isMinimizable(){return _("plugin:window|is_minimizable",{label:this.label})}async isClosable(){return _("plugin:window|is_closable",{label:this.label})}async isVisible(){return _("plugin:window|is_visible",{label:this.label})}async title(){return _("plugin:window|title",{label:this.label})}async theme(){return _("plugin:window|theme",{label:this.label})}async center(){return _("plugin:window|center",{label:this.label})}async requestUserAttention(t){let n=null;return t&&(t===Ol.Critical?n={type:"Critical"}:n={type:"Informational"}),_("plugin:window|request_user_attention",{label:this.label,value:n})}async setResizable(t){return _("plugin:window|set_resizable",{label:this.label,value:t})}async setMaximizable(t){return _("plugin:window|set_maximizable",{label:this.label,value:t})}async setMinimizable(t){return _("plugin:window|set_minimizable",{label:this.label,value:t})}async setClosable(t){return _("plugin:window|set_closable",{label:this.label,value:t})}async setTitle(t){return _("plugin:window|set_title",{label:this.label,value:t})}async maximize(){return _("plugin:window|maximize",{label:this.label})}async unmaximize(){return _("plugin:window|unmaximize",{label:this.label})}async toggleMaximize(){return _("plugin:window|toggle_maximize",{label:this.label})}async minimize(){return _("plugin:window|minimize",{label:this.label})}async unminimize(){return _("plugin:window|unminimize",{label:this.label})}async show(){return _("plugin:window|show",{label:this.label})}async hide(){return _("plugin:window|hide",{label:this.label})}async close(){return _("plugin:window|close",{label:this.label})}async setDecorations(t){return _("plugin:window|set_decorations",{label:this.label,value:t})}async setShadow(t){return _("plugin:window|set_shadow",{label:this.label,value:t})}async setEffects(t){return _("plugin:window|set_effects",{label:this.label,value:t})}async clearEffects(){return _("plugin:window|set_effects",{label:this.label,value:null})}async setAlwaysOnTop(t){return _("plugin:window|set_always_on_top",{label:this.label,value:t})}async setAlwaysOnBottom(t){return _("plugin:window|set_always_on_bottom",{label:this.label,value:t})}async setContentProtected(t){return _("plugin:window|set_content_protected",{label:this.label,value:t})}async setSize(t){if(!t||t.type!=="Logical"&&t.type!=="Physical")throw new Error("the `size` argument must be either a LogicalSize or a PhysicalSize instance");return _("plugin:window|set_size",{label:this.label,value:{type:t.type,data:{width:t.width,height:t.height}}})}async setMinSize(t){if(t&&t.type!=="Logical"&&t.type!=="Physical")throw new Error("the `size` argument must be either a LogicalSize or a PhysicalSize instance");return _("plugin:window|set_min_size",{label:this.label,value:t?{type:t.type,data:{width:t.width,height:t.height}}:null})}async setMaxSize(t){if(t&&t.type!=="Logical"&&t.type!=="Physical")throw new Error("the `size` argument must be either a LogicalSize or a PhysicalSize instance");return _("plugin:window|set_max_size",{label:this.label,value:t?{type:t.type,data:{width:t.width,height:t.height}}:null})}async setPosition(t){if(!t||t.type!=="Logical"&&t.type!=="Physical")throw new Error("the `position` argument must be either a LogicalPosition or a PhysicalPosition instance");return _("plugin:window|set_position",{label:this.label,value:{type:t.type,data:{x:t.x,y:t.y}}})}async setFullscreen(t){return _("plugin:window|set_fullscreen",{label:this.label,value:t})}async setFocus(){return _("plugin:window|set_focus",{label:this.label})}async setIcon(t){return _("plugin:window|set_icon",{label:this.label,value:typeof t=="string"?t:Array.from(t)})}async setSkipTaskbar(t){return _("plugin:window|set_skip_taskbar",{label:this.label,value:t})}async setCursorGrab(t){return _("plugin:window|set_cursor_grab",{label:this.label,value:t})}async setCursorVisible(t){return _("plugin:window|set_cursor_visible",{label:this.label,value:t})}async setCursorIcon(t){return _("plugin:window|set_cursor_icon",{label:this.label,value:t})}async setCursorPosition(t){if(!t||t.type!=="Logical"&&t.type!=="Physical")throw new Error("the `position` argument must be either a LogicalPosition or a PhysicalPosition instance");return _("plugin:window|set_cursor_position",{label:this.label,value:{type:t.type,data:{x:t.x,y:t.y}}})}async setIgnoreCursorEvents(t){return _("plugin:window|set_ignore_cursor_events",{label:this.label,value:t})}async startDragging(){return _("plugin:window|start_dragging",{label:this.label})}async setProgressBar(t){return _("plugin:window|set_progress_bar",{label:this.label,value:t})}async onResized(t){return this.listen(Se.WINDOW_RESIZED,n=>{n.payload=mo(n.payload),t(n)})}async onMoved(t){return this.listen(Se.WINDOW_MOVED,n=>{n.payload=go(n.payload),t(n)})}async onCloseRequested(t){return this.listen(Se.WINDOW_CLOSE_REQUESTED,n=>{const i=new _o(n);Promise.resolve(t(i)).then(()=>{if(!i.isPreventDefault())return this.close()})})}async onFocusChanged(t){const n=await this.listen(Se.WINDOW_FOCUS,o=>{t({...o,payload:!0})}),i=await this.listen(Se.WINDOW_BLUR,o=>{t({...o,payload:!1})});return()=>{n(),i()}}async onScaleChanged(t){return this.listen(Se.WINDOW_SCALE_FACTOR_CHANGED,t)}async onMenuClicked(t){return this.listen(Se.MENU,t)}async onFileDropEvent(t){const n=await this.listen(Se.WINDOW_FILE_DROP,r=>{t({...r,payload:{type:"drop",paths:r.payload}})}),i=await this.listen(Se.WINDOW_FILE_DROP_HOVER,r=>{t({...r,payload:{type:"hover",paths:r.payload}})}),o=await this.listen(Se.WINDOW_FILE_DROP_CANCELLED,r=>{t({...r,payload:{type:"cancel"}})});return()=>{n(),i(),o()}}async onThemeChanged(t){return this.listen(Se.WINDOW_THEME_CHANGED,t)}}var Il;(function(e){e.AppearanceBased="appearanceBased",e.Light="light",e.Dark="dark",e.MediumLight="mediumLight",e.UltraDark="ultraDark",e.Titlebar="titlebar",e.Selection="selection",e.Menu="menu",e.Popover="popover",e.Sidebar="sidebar",e.HeaderView="headerView",e.Sheet="sheet",e.WindowBackground="windowBackground",e.HudWindow="hudWindow",e.FullScreenUI="fullScreenUI",e.Tooltip="tooltip",e.ContentBackground="contentBackground",e.UnderWindowBackground="underWindowBackground",e.UnderPageBackground="underPageBackground",e.Mica="mica",e.Blur="blur",e.Acrylic="acrylic",e.Tabbed="tabbed",e.TabbedDark="tabbedDark",e.TabbedLight="tabbedLight"})(Il||(Il={}));var Ml;(function(e){e.FollowsWindowActiveState="followsWindowActiveState",e.Active="active",e.Inactive="inactive"})(Ml||(Ml={}));function go(e){return new zt(e.x,e.y)}function mo(e){return new en(e.width,e.height)}function ds(e,t,n){const i=e.slice();return i[105]=t[n],i}function fs(e,t,n){const i=e.slice();return i[108]=t[n],i}function hs(e,t,n){const i=e.slice();return i[111]=t[n],i}function ps(e,t,n){const i=e.slice();return i[114]=t[n],i}function bs(e,t,n){const i=e.slice();return i[117]=t[n],i}function _s(e){let t,n,i,o,r,g,h=ye(Object.keys(e[1])),b=[];for(let d=0;de[59].call(i))},m(d,W){w(d,t,W),w(d,n,W),w(d,i,W),l(i,o);for(let L=0;Le[83].call(Je)),a(ut,"class","input"),a(ut,"type","number"),a(ct,"class","input"),a(ct,"type","number"),a(Ze,"class","flex gap-2"),a(dt,"class","input grow"),a(dt,"id","title"),a(mn,"class","btn"),a(mn,"type","submit"),a(Lt,"class","flex gap-1"),a(gn,"class","flex flex-col gap-1"),a(xe,"class","input"),e[26]===void 0&&ht(()=>e[87].call(xe)),a(Ye,"class","input"),a(Ye,"type","number"),a(Ye,"min","0"),a(Ye,"max","100"),a(Xt,"class","flex gap-2"),a(wn,"class","flex flex-col gap-1")},m(u,f){w(u,t,f),w(u,n,f),w(u,i,f),l(i,o),l(i,r),l(i,g),l(g,h),E(h,e[43]),l(g,b),l(g,d),w(u,W,f),w(u,L,f),w(u,Y,f),w(u,S,f),l(S,I),l(S,M),l(S,D),l(S,ae),l(S,H),l(S,N),l(S,V),w(u,G,f),w(u,O,f),l(O,B),l(B,re),l(B,T),T.checked=e[6],l(O,x),l(O,te),l(te,y),l(te,F),F.checked=e[2],l(O,j),l(O,$),l($,ue),l($,K),K.checked=e[3],l(O,ge),l(O,ke),l(ke,de),l(ke,oe),oe.checked=e[4],l(O,Q),l(O,he),l(he,U),l(he,ne),ne.checked=e[5],l(O,J),l(O,v),l(v,X),l(v,z),z.checked=e[7],l(O,fe),l(O,ze),l(ze,me),l(ze,pe),pe.checked=e[8],l(O,We),l(O,Pe),l(Pe,Ae),l(Pe,be),be.checked=e[9],l(O,_e),l(O,Le),l(Le,Oe),l(Le,ce),ce.checked=e[10],l(O,Ce),l(O,le),l(le,De),l(le,Ne),Ne.checked=e[11],w(u,Ee,f),w(u,ie,f),w(u,C,f),w(u,Z,f),l(Z,P),l(P,Ie),l(Ie,Sn),l(Ie,Te),E(Te,e[18]),l(P,zn),l(P,Et),l(Et,Pn),l(Et,Re),E(Re,e[19]),l(Z,On),l(Z,$e),l($e,It),l(It,En),l(It,He),E(He,e[12]),l($e,In),l($e,Mt),l(Mt,Mn),l(Mt,Fe),E(Fe,e[13]),l(Z,Wn),l(Z,et),l(et,Wt),l(Wt,An),l(Wt,Ve),E(Ve,e[14]),l(et,Dn),l(et,At),l(At,Nn),l(At,Ge),E(Ge,e[15]),l(Z,Tn),l(Z,tt),l(tt,Dt),l(Dt,Rn),l(Dt,Ue),E(Ue,e[16]),l(tt,Hn),l(tt,Nt),l(Nt,Fn),l(Nt,qe),E(qe,e[17]),w(u,ln,f),w(u,sn,f),w(u,on,f),w(u,Me,f),l(Me,nt),l(nt,Xe),l(Xe,A),l(Xe,an),l(Xe,pt),l(pt,rn),l(pt,Tt),l(Xe,un),l(Xe,_t),l(_t,cn),l(_t,Rt),l(nt,dn),l(nt,Be),l(Be,mt),l(Be,fn),l(Be,wt),l(wt,hn),l(wt,Ht),l(Be,pn),l(Be,yt),l(yt,bn),l(yt,Ft),l(Me,Un),l(Me,Ut),l(Ut,lt),l(lt,qn),l(lt,pi),l(lt,Bn),l(Bn,bi),l(Bn,Wl),l(lt,_i),l(lt,Vn),l(Vn,gi),l(Vn,Al),l(Ut,mi),l(Ut,it),l(it,Xn),l(it,wi),l(it,Yn),l(Yn,vi),l(Yn,Dl),l(it,yi),l(it,Qn),l(Qn,ki),l(Qn,Nl),l(Me,Li),l(Me,qt),l(qt,st),l(st,Jn),l(st,Ci),l(st,xn),l(xn,Si),l(xn,Tl),l(st,zi),l(st,el),l(el,Pi),l(el,Rl),l(qt,Oi),l(qt,ot),l(ot,nl),l(ot,Ei),l(ot,ll),l(ll,Ii),l(ll,Hl),l(ot,Mi),l(ot,sl),l(sl,Wi),l(sl,Fl),l(Me,Ai),l(Me,Bt),l(Bt,at),l(at,al),l(at,Di),l(at,rl),l(rl,Ni),l(rl,Ul),l(at,Ti),l(at,cl),l(cl,Ri),l(cl,ql),l(Bt,Hi),l(Bt,rt),l(rt,fl),l(rt,Fi),l(rt,hl),l(hl,Ui),l(hl,Bl),l(rt,qi),l(rt,bl),l(bl,Bi),l(bl,jl),w(u,Vl,f),w(u,Gl,f),w(u,Xl,f),w(u,_n,f),w(u,Yl,f),w(u,Qe,f),l(Qe,gl),l(gl,jt),jt.checked=e[20],l(gl,ji),l(Qe,Vi),l(Qe,ml),l(ml,Vt),Vt.checked=e[21],l(ml,Gi),l(Qe,Xi),l(Qe,wl),l(wl,Gt),Gt.checked=e[25],l(wl,Yi),w(u,Kl,f),w(u,Ze,f),l(Ze,vl),l(vl,Ki),l(vl,Je);for(let R=0;Re[89].call(r)),a(d,"class","input"),e[37]===void 0&&ht(()=>e[90].call(d)),a(S,"class","input"),a(S,"type","number"),a(n,"class","flex"),Qt(N,"max-width","120px"),a(N,"class","input"),a(N,"type","number"),a(N,"placeholder","R"),Qt(G,"max-width","120px"),a(G,"class","input"),a(G,"type","number"),a(G,"placeholder","G"),Qt(B,"max-width","120px"),a(B,"class","input"),a(B,"type","number"),a(B,"placeholder","B"),Qt(T,"max-width","120px"),a(T,"class","input"),a(T,"type","number"),a(T,"placeholder","A"),a(H,"class","flex"),a(M,"class","flex"),a(y,"class","btn"),Qt(y,"width","80px"),a(te,"class","flex"),a(de,"class","btn"),Qt(de,"width","80px"),a(j,"class","flex"),a(t,"class","flex flex-col gap-1")},m(v,X){w(v,t,X),l(t,n),l(n,i),l(i,o),l(i,r);for(let z=0;z=1,W,L,Y,S=d&&_s(e),I=e[1][e[0]]&&ms(e);return{c(){t=s("div"),n=s("div"),i=s("input"),o=c(),r=s("button"),r.textContent="New window",g=c(),h=s("br"),b=c(),S&&S.c(),W=c(),I&&I.c(),a(i,"class","input grow"),a(i,"type","text"),a(i,"placeholder","New Window label.."),a(r,"class","btn"),a(n,"class","flex gap-1"),a(t,"class","flex flex-col children:grow gap-2")},m(M,D){w(M,t,D),l(t,n),l(n,i),E(i,e[28]),l(n,o),l(n,r),l(t,g),l(t,h),l(t,b),S&&S.m(t,null),l(t,W),I&&I.m(t,null),L||(Y=[k(i,"input",e[58]),k(r,"click",e[53])],L=!0)},p(M,D){D[0]&268435456&&i.value!==M[28]&&E(i,M[28]),D[0]&2&&(d=Object.keys(M[1]).length>=1),d?S?S.p(M,D):(S=_s(M),S.c(),S.m(t,W)):S&&(S.d(1),S=null),M[1][M[0]]?I?I.p(M,D):(I=ms(M),I.c(),I.m(t,null)):I&&(I.d(1),I=null)},i:ee,o:ee,d(M){M&&m(t),S&&S.d(),I&&I.d(),L=!1,je(Y)}}}function yo(e,t,n){const i=Ts();let o=i.label;const r={[i.label]:i},g=["default","crosshair","hand","arrow","move","text","wait","help","progress","notAllowed","contextMenu","cell","verticalText","alias","copy","noDrop","grab","grabbing","allScroll","zoomIn","zoomOut","eResize","nResize","neResize","nwResize","sResize","seResize","swResize","wResize","ewResize","nsResize","neswResize","nwseResize","colResize","rowResize"],h=["mica","blur","acrylic","tabbed","tabbedDark","tabbedLight"],b=navigator.appVersion.includes("Windows"),d=navigator.appVersion.includes("Macintosh");let W=b?h:Object.keys(Il).map(A=>Il[A]).filter(A=>!h.includes(A));const L=Object.keys(Ml).map(A=>Ml[A]),Y=Object.keys(El).map(A=>El[A]);let{onMessage:S}=t;const I=document.querySelector("main");let M,D=!0,ae=!0,H=!0,N=!0,V=!1,G=!0,O=!1,B=!1,re=!0,T=!1,x=null,te=null,y=null,F=null,j=null,$=null,ue=null,K=null,ge=1,ke=new zt(ue,K),de=new zt(ue,K),oe=new en(x,te),Q=new en(x,te),he,U,ne=!1,J=!0,v=null,X=null,z="default",fe=!1,ze="Awesome Tauri Example!",me=[],pe,We,Pe,Ae,be,_e,Le,Oe="none",ce=0,Ce;function le(){r[o].setTitle(ze)}function De(){r[o].hide(),setTimeout(r[o].show,2e3)}function Ne(){r[o].minimize(),setTimeout(r[o].unminimize,2e3)}function Ee(){if(!M)return;const A=new Cn(M);n(1,r[M]=A,r),A.once("tauri://error",function(){S("Error creating new webview")})}function ie(){r[o].innerSize().then(A=>{n(32,oe=A),n(12,x=oe.width),n(13,te=oe.height)}),r[o].outerSize().then(A=>{n(33,Q=A)})}function C(){r[o].innerPosition().then(A=>{n(30,ke=A)}),r[o].outerPosition().then(A=>{n(31,de=A),n(18,ue=de.x),n(19,K=de.y)})}async function Z(A){A&&(he&&he(),U&&U(),U=await A.listen("tauri://move",C),he=await A.listen("tauri://resize",ie))}async function P(){await r[o].minimize(),await r[o].requestUserAttention(Ol.Critical),await new Promise(A=>setTimeout(A,3e3)),await r[o].requestUserAttention(null)}async function Ie(){me.includes(pe)||n(35,me=[...me,pe]);const A={effects:me,state:We,radius:Pe};Number.isInteger(Ae)&&Number.isInteger(be)&&Number.isInteger(_e)&&Number.isInteger(Le)&&(A.color=[Ae,be,_e,Le]),I.classList.remove("bg-primary"),I.classList.remove("dark:bg-darkPrimary"),await r[o].clearEffects(),await r[o].setEffects(A)}async function Sn(){n(35,me=[]),await r[o].clearEffects(),I.classList.add("bg-primary"),I.classList.add("dark:bg-darkPrimary")}function Te(){M=this.value,n(28,M)}function zn(){o=yn(this),n(0,o),n(1,r)}function Et(){Ce=this.value,n(43,Ce)}const Pn=()=>r[o].center();function Re(){V=this.checked,n(6,V)}function On(){D=this.checked,n(2,D)}function $e(){ae=this.checked,n(3,ae)}function It(){H=this.checked,n(4,H)}function En(){N=this.checked,n(5,N)}function He(){G=this.checked,n(7,G)}function In(){O=this.checked,n(8,O)}function Mt(){B=this.checked,n(9,B)}function Mn(){re=this.checked,n(10,re)}function Fe(){T=this.checked,n(11,T)}function Wn(){ue=q(this.value),n(18,ue)}function et(){K=q(this.value),n(19,K)}function Wt(){x=q(this.value),n(12,x)}function An(){te=q(this.value),n(13,te)}function Ve(){y=q(this.value),n(14,y)}function Dn(){F=q(this.value),n(15,F)}function At(){j=q(this.value),n(16,j)}function Nn(){$=q(this.value),n(17,$)}function Ge(){ne=this.checked,n(20,ne)}function Tn(){J=this.checked,n(21,J)}function tt(){fe=this.checked,n(25,fe)}function Dt(){z=yn(this),n(24,z),n(44,g)}function Rn(){v=q(this.value),n(22,v)}function Ue(){X=q(this.value),n(23,X)}function Hn(){ze=this.value,n(34,ze)}function Nt(){Oe=yn(this),n(26,Oe),n(49,Y)}function Fn(){ce=q(this.value),n(27,ce)}function qe(){pe=yn(this),n(36,pe),n(47,W)}function ln(){We=yn(this),n(37,We),n(48,L)}function sn(){Pe=q(this.value),n(38,Pe)}function on(){Ae=q(this.value),n(39,Ae)}function Me(){be=q(this.value),n(40,be)}function nt(){_e=q(this.value),n(41,_e)}function Xe(){Le=q(this.value),n(42,Le)}return e.$$set=A=>{"onMessage"in A&&n(57,S=A.onMessage)},e.$$.update=()=>{var A,an,pt,rn,bt,Tt,un,_t,cn,gt,Rt,dn,Be,mt,fn,wt,hn,vt,Ht,pn,yt,bn,kt,Ft;e.$$.dirty[0]&3&&(r[o],C(),ie()),e.$$.dirty[0]&7&&((A=r[o])==null||A.setResizable(D)),e.$$.dirty[0]&11&&((an=r[o])==null||an.setMaximizable(ae)),e.$$.dirty[0]&19&&((pt=r[o])==null||pt.setMinimizable(H)),e.$$.dirty[0]&35&&((rn=r[o])==null||rn.setClosable(N)),e.$$.dirty[0]&67&&(V?(bt=r[o])==null||bt.maximize():(Tt=r[o])==null||Tt.unmaximize()),e.$$.dirty[0]&131&&((un=r[o])==null||un.setDecorations(G)),e.$$.dirty[0]&259&&((_t=r[o])==null||_t.setAlwaysOnTop(O)),e.$$.dirty[0]&515&&((cn=r[o])==null||cn.setAlwaysOnBottom(B)),e.$$.dirty[0]&1027&&((gt=r[o])==null||gt.setContentProtected(re)),e.$$.dirty[0]&2051&&((Rt=r[o])==null||Rt.setFullscreen(T)),e.$$.dirty[0]&12291&&x&&te&&((dn=r[o])==null||dn.setSize(new en(x,te))),e.$$.dirty[0]&49155&&(y&&F?(Be=r[o])==null||Be.setMinSize(new di(y,F)):(mt=r[o])==null||mt.setMinSize(null)),e.$$.dirty[0]&196611&&(j>800&&$>400?(fn=r[o])==null||fn.setMaxSize(new di(j,$)):(wt=r[o])==null||wt.setMaxSize(null)),e.$$.dirty[0]&786435&&ue!==null&&K!==null&&((hn=r[o])==null||hn.setPosition(new zt(ue,K))),e.$$.dirty[0]&3&&((vt=r[o])==null||vt.scaleFactor().then(Un=>n(29,ge=Un))),e.$$.dirty[0]&3&&Z(r[o]),e.$$.dirty[0]&1048579&&((Ht=r[o])==null||Ht.setCursorGrab(ne)),e.$$.dirty[0]&2097155&&((pn=r[o])==null||pn.setCursorVisible(J)),e.$$.dirty[0]&16777219&&((yt=r[o])==null||yt.setCursorIcon(z)),e.$$.dirty[0]&12582915&&v!==null&&X!==null&&((bn=r[o])==null||bn.setCursorPosition(new zt(v,X))),e.$$.dirty[0]&33554435&&((kt=r[o])==null||kt.setIgnoreCursorEvents(fe)),e.$$.dirty[0]&201326595&&((Ft=r[o])==null||Ft.setProgressBar({status:Oe,progress:ce}))},[o,r,D,ae,H,N,V,G,O,B,re,T,x,te,y,F,j,$,ue,K,ne,J,v,X,z,fe,Oe,ce,M,ge,ke,de,oe,Q,ze,me,pe,We,Pe,Ae,be,_e,Le,Ce,g,b,d,W,L,Y,le,De,Ne,Ee,P,Ie,Sn,S,Te,zn,Et,Pn,Re,On,$e,It,En,He,In,Mt,Mn,Fe,Wn,et,Wt,An,Ve,Dn,At,Nn,Ge,Tn,tt,Dt,Rn,Ue,Hn,Nt,Fn,qe,ln,sn,on,Me,nt,Xe]}class ko extends nn{constructor(t){super(),tn(this,t,yo,vo,Ot,{onMessage:57},null,[-1,-1,-1,-1])}}function Lo(e){let t;return{c(){t=s("div"),t.innerHTML='
Not available for Linux
',a(t,"class","flex flex-col gap-2")},m(n,i){w(n,t,i)},p:ee,i:ee,o:ee,d(n){n&&m(t)}}}function Co(e,t,n){let{onMessage:i}=t;const o=window.constraints={audio:!0,video:!0};function r(h){const b=document.querySelector("video"),d=h.getVideoTracks();i("Got stream with constraints:",o),i(`Using video device: ${d[0].label}`),window.stream=h,b.srcObject=h}function g(h){if(h.name==="ConstraintNotSatisfiedError"){const b=o.video;i(`The resolution ${b.width.exact}x${b.height.exact} px is not supported by your device.`)}else h.name==="PermissionDeniedError"&&i("Permissions have not been granted to use your camera and microphone, you need to allow the page access to your devices in order for the demo to work.");i(`getUserMedia error: ${h.name}`,h)}return Pl(async()=>{try{const h=await navigator.mediaDevices.getUserMedia(o);r(h)}catch(h){g(h)}}),Ws(()=>{window.stream.getTracks().forEach(function(h){h.stop()})}),e.$$set=h=>{"onMessage"in h&&n(0,i=h.onMessage)},[i]}class So extends nn{constructor(t){super(),tn(this,t,Co,Lo,Ot,{onMessage:0})}}function zo(e){let t,n,i,o,r,g;return{c(){t=s("div"),n=s("button"),n.textContent="Show",i=c(),o=s("button"),o.textContent="Hide",a(n,"class","btn"),a(n,"id","show"),a(n,"title","Hides and shows the app after 2 seconds"),a(o,"class","btn"),a(o,"id","hide")},m(h,b){w(h,t,b),l(t,n),l(t,i),l(t,o),r||(g=[k(n,"click",e[0]),k(o,"click",e[1])],r=!0)},p:ee,i:ee,o:ee,d(h){h&&m(t),r=!1,je(g)}}}function Po(e,t,n){let{onMessage:i}=t;function o(){r().then(()=>{setTimeout(()=>{so().then(()=>i("Shown app")).catch(i)},2e3)}).catch(i)}function r(){return oo().then(()=>i("Hide app")).catch(i)}return e.$$set=g=>{"onMessage"in g&&n(2,i=g.onMessage)},[o,r,i]}class Oo extends nn{constructor(t){super(),tn(this,t,Po,zo,Ot,{onMessage:2})}}function Ls(e,t,n){const i=e.slice();return i[25]=t[n],i}function Cs(e,t,n){const i=e.slice();return i[28]=t[n],i}function Eo(e){let t;return{c(){t=s("span"),a(t,"class","i-codicon-menu animate-duration-300ms animate-fade-in")},m(n,i){w(n,t,i)},d(n){n&&m(t)}}}function Io(e){let t;return{c(){t=s("span"),a(t,"class","i-codicon-close animate-duration-300ms animate-fade-in")},m(n,i){w(n,t,i)},d(n){n&&m(t)}}}function Mo(e){let t,n;return{c(){t=p(`Switch to Dark mode - `),n=s("div"),a(n,"class","i-ph-moon")},m(i,o){w(i,t,o),w(i,n,o)},d(i){i&&(m(t),m(n))}}}function Wo(e){let t,n;return{c(){t=p(`Switch to Light mode - `),n=s("div"),a(n,"class","i-ph-sun")},m(i,o){w(i,t,o),w(i,n,o)},d(i){i&&(m(t),m(n))}}}function Ao(e){let t,n,i,o,r,g,h;function b(){return e[14](e[28])}return{c(){t=s("a"),n=s("div"),i=c(),o=s("p"),o.textContent=`${e[28].label}`,a(n,"class",e[28].icon+" mr-2"),a(t,"href","##"),a(t,"class",r="nv "+(e[1]===e[28]?"nv_selected":""))},m(d,W){w(d,t,W),l(t,n),l(t,i),l(t,o),g||(h=k(t,"click",b),g=!0)},p(d,W){e=d,W&2&&r!==(r="nv "+(e[1]===e[28]?"nv_selected":""))&&a(t,"class",r)},d(d){d&&m(t),g=!1,h()}}}function Ss(e){let t,n=e[28]&&Ao(e);return{c(){n&&n.c(),t=fi()},m(i,o){n&&n.m(i,o),w(i,t,o)},p(i,o){i[28]&&n.p(i,o)},d(i){i&&m(t),n&&n.d(i)}}}function zs(e){let t,n=e[25].html+"",i;return{c(){t=new Gs(!1),i=fi(),t.a=i},m(o,r){t.m(n,o,r),w(o,i,r)},p(o,r){r&16&&n!==(n=o[25].html+"")&&t.p(n)},d(o){o&&(m(i),t.d())}}}function Do(e){let t,n,i,o,r,g,h,b,d,W,L,Y,S,I,M,D,ae,H,N,V,G,O,B,re,T,x,te,y,F,j,$,ue,K=e[1].label+"",ge,ke,de,oe,Q,he,U,ne,J,v,X,z,fe,ze,me,pe,We,Pe;function Ae(C,Z){return C[0]?Io:Eo}let be=Ae(e),_e=be(e);function Le(C,Z){return C[2]?Wo:Mo}let Oe=Le(e),ce=Oe(e),Ce=ye(e[5]),le=[];for(let C=0;C`,ae=c(),H=s("a"),H.innerHTML=`GitHub - `,N=c(),V=s("a"),V.innerHTML=`Source - `,G=c(),O=s("br"),B=c(),re=s("div"),T=c(),x=s("br"),te=c(),y=s("div");for(let C=0;C',ze=c(),me=s("div");for(let C=0;C{ci(P,1)}),Js()}De?(Q=os(De,Ne(C)),us(Q.$$.fragment),ri(Q.$$.fragment,1),ui(Q,oe,null)):Q=null}if(Z&16){Ee=ye(C[4]);let P;for(P=0;P{y.ctrlKey&&y.key==="b"&&_("toggle_menu")});const o=navigator.userAgent.toLowerCase(),r=o.includes("android")||o.includes("iphone"),g=[{label:"Welcome",component:uo,icon:"i-ph-hand-waving"},{label:"Communication",component:po,icon:"i-codicon-radio-tower"},!r&&{label:"App",component:Oo,icon:"i-codicon-hubot"},{label:"Window",component:ko,icon:"i-codicon-window"},{label:"WebRTC",component:So,icon:"i-ph-broadcast"}];let h=g[0];function b(y){n(1,h=y)}let d;Pl(()=>{n(2,d=localStorage&&localStorage.getItem("theme")=="dark"),Os(d)});function W(){n(2,d=!d),Os(d)}let L=eo([]);Bs(e,L,y=>n(4,i=y));function Y(y){L.update(F=>[{html:`
[${new Date().toLocaleTimeString()}]: `+(typeof y=="string"?y:JSON.stringify(y,null,1))+"
"},...F])}function S(y){L.update(F=>[{html:`
[${new Date().toLocaleTimeString()}]: `+y+"
"},...F])}function I(){L.update(()=>[])}let M,D,ae;function H(y){ae=y.clientY;const F=window.getComputedStyle(M);D=parseInt(F.height,10);const j=ue=>{const K=ue.clientY-ae,ge=D-K;n(3,M.style.height=`${ge{document.removeEventListener("mouseup",$),document.removeEventListener("mousemove",j)};document.addEventListener("mouseup",$),document.addEventListener("mousemove",j)}let N=!1,V,G,O=!1,B=0,re=0;const T=(y,F,j)=>Math.min(Math.max(F,y),j);Pl(()=>{n(13,V=document.querySelector("#sidebar")),G=document.querySelector("#sidebarToggle"),document.addEventListener("click",y=>{G.contains(y.target)?n(0,N=!N):N&&!V.contains(y.target)&&n(0,N=!1)}),document.addEventListener("touchstart",y=>{if(G.contains(y.target))return;const F=y.touches[0].clientX;(0{if(O){const F=y.touches[0].clientX;re=F;const j=(F-B)/10;V.style.setProperty("--translate-x",`-${T(0,N?0-j:18.75-j,18.75)}rem`)}}),document.addEventListener("touchend",()=>{if(O){const y=(re-B)/10;n(0,N=N?y>-(18.75/2):y>18.75/2)}O=!1})});const x=y=>{b(y),n(0,N=!1)};function te(y){oi[y?"unshift":"push"](()=>{M=y,n(3,M)})}return e.$$.update=()=>{if(e.$$.dirty&1){const y=document.querySelector("#sidebar");y&&No(y,N)}},[N,h,d,M,i,g,b,W,L,Y,S,I,H,V,x,te]}class Ro extends nn{constructor(t){super(),tn(this,t,To,Do,Ot,{})}}new Ro({target:document.querySelector("#app")}); + tests.`,l=p(),s=r("br"),u=p(),d=r("br"),o=p(),c=r("pre"),h=w(" App name: "),k=r("code"),b=w(t[2]),O=w(` + App version: `),_=r("code"),P=w(t[0]),v=w(` + Tauri version: `),E=r("code"),V=w(t[1]),D=w(` + `),L=p(),W=r("br"),A=p(),I=r("button"),I.textContent="Context menu",a(I,"class","btn")},m(q,Q){S(q,e,Q),i(e,n),i(e,l),i(e,s),i(e,u),i(e,d),i(e,o),i(e,c),i(c,h),i(c,k),i(k,b),i(c,O),i(c,_),i(_,P),i(c,v),i(c,E),i(E,V),i(c,D),i(e,L),i(e,W),i(e,A),i(e,I),R||(Y=M(I,"click",t[3]),R=!0)},p(q,[Q]){Q&4&&se(b,q[2]),Q&1&&se(P,q[0]),Q&2&&se(V,q[1])},i:ne,o:ne,d(q){q&&C(e),R=!1,Y()}}}function jr(t,e,n){let l="1.0.0",s="1.0.0",u="Unknown";Ur().then(o=>{n(2,u=o)}),Hr().then(o=>{n(0,l=o)}),Br().then(o=>{n(1,s=o)});function d(){m("popup_context_menu")}return[l,s,u,d]}class Gr extends $e{constructor(e){super(),Ze(this,e,jr,Nr,je,{})}}var ze;(function(t){t.WINDOW_RESIZED="tauri://resize",t.WINDOW_MOVED="tauri://move",t.WINDOW_CLOSE_REQUESTED="tauri://close-requested",t.WINDOW_CREATED="tauri://window-created",t.WINDOW_DESTROYED="tauri://destroyed",t.WINDOW_FOCUS="tauri://focus",t.WINDOW_BLUR="tauri://blur",t.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",t.WINDOW_THEME_CHANGED="tauri://theme-changed",t.WINDOW_FILE_DROP="tauri://file-drop",t.WINDOW_FILE_DROP_HOVER="tauri://file-drop-hover",t.WINDOW_FILE_DROP_CANCELLED="tauri://file-drop-cancelled"})(ze||(ze={}));async function ar(t,e){await m("plugin:event|unlisten",{event:t,eventId:e})}async function El(t,e,n){return m("plugin:event|listen",{event:t,windowLabel:n==null?void 0:n.target,handler:sr(e)}).then(l=>async()=>ar(t,l))}async function Kr(t,e,n){return El(t,l=>{e(l),ar(t,l.id).catch(()=>{})},n)}async function ur(t,e,n){await m("plugin:event|emit",{event:t,windowLabel:n==null?void 0:n.target,payload:e})}function Xr(t){let e,n,l,s,u,d,o,c;return{c(){e=r("div"),n=r("button"),n.textContent="Call Log API",l=p(),s=r("button"),s.textContent="Call Request (async) API",u=p(),d=r("button"),d.textContent="Send event to Rust",a(n,"class","btn"),a(n,"id","log"),a(s,"class","btn"),a(s,"id","request"),a(d,"class","btn"),a(d,"id","event")},m(h,k){S(h,e,k),i(e,n),i(e,l),i(e,s),i(e,u),i(e,d),o||(c=[M(n,"click",t[0]),M(s,"click",t[1]),M(d,"click",t[2])],o=!0)},p:ne,i:ne,o:ne,d(h){h&&C(e),o=!1,Ce(c)}}}function Yr(t,e,n){let{onMessage:l}=e,s;Vi(async()=>{s=await El("rust-event",l)}),er(()=>{s&&s()});function u(){m("log_operation",{event:"tauri-click",payload:"this payload is optional because we used Option in Rust"})}function d(){m("perform_request",{endpoint:"dummy endpoint arg",body:{id:5,name:"test"}}).then(l).catch(l)}function o(){ur("js-event","this is the payload string")}return t.$$set=c=>{"onMessage"in c&&n(3,l=c.onMessage)},[u,d,o,l]}class Qr extends $e{constructor(e){super(),Ze(this,e,Yr,Xr,je,{onMessage:3})}}class Ll{constructor(e,n){this.type="Logical",this.width=e,this.height=n}}class ln{constructor(e,n){this.type="Physical",this.width=e,this.height=n}toLogical(e){return new Ll(this.width/e,this.height/e)}}class Jr{constructor(e,n){this.type="Logical",this.x=e,this.y=n}}class it{constructor(e,n){this.type="Physical",this.x=e,this.y=n}toLogical(e){return new Jr(this.x/e,this.y/e)}}var Ni;(function(t){t[t.Critical=1]="Critical",t[t.Informational=2]="Informational"})(Ni||(Ni={}));class Zr{constructor(e){this._preventDefault=!1,this.event=e.event,this.windowLabel=e.windowLabel,this.id=e.id}preventDefault(){this._preventDefault=!0}isPreventDefault(){return this._preventDefault}}var ji;(function(t){t.None="none",t.Normal="normal",t.Indeterminate="indeterminate",t.Paused="paused",t.Error="error"})(ji||(ji={}));function or(){return new Rn(window.__TAURI_INTERNALS__.metadata.currentWindow.label,{skip:!0})}function kl(){return window.__TAURI_INTERNALS__.metadata.windows.map(t=>new Rn(t.label,{skip:!0}))}const Ss=["tauri://created","tauri://error"];class Rn{constructor(e,n={}){this.label=e,this.listeners=Object.create(null),n!=null&&n.skip||m("plugin:window|create",{options:{...n,label:e}}).then(async()=>this.emit("tauri://created")).catch(async l=>this.emit("tauri://error",l))}static getByLabel(e){return kl().some(n=>n.label===e)?new Rn(e,{skip:!0}):null}static getCurrent(){return or()}static getAll(){return kl()}static async getFocusedWindow(){for(const e of kl())if(await e.isFocused())return e;return null}async listen(e,n){return this._handleTauriEvent(e,n)?Promise.resolve(()=>{const l=this.listeners[e];l.splice(l.indexOf(n),1)}):El(e,n,{target:this.label})}async once(e,n){return this._handleTauriEvent(e,n)?Promise.resolve(()=>{const l=this.listeners[e];l.splice(l.indexOf(n),1)}):Kr(e,n,{target:this.label})}async emit(e,n){if(Ss.includes(e)){for(const l of this.listeners[e]||[])l({event:e,id:-1,windowLabel:this.label,payload:n});return Promise.resolve()}return ur(e,n,{target:this.label})}_handleTauriEvent(e,n){return Ss.includes(e)?(e in this.listeners?this.listeners[e].push(n):this.listeners[e]=[n],!0):!1}async scaleFactor(){return m("plugin:window|scale_factor",{label:this.label})}async innerPosition(){return m("plugin:window|inner_position",{label:this.label}).then(({x:e,y:n})=>new it(e,n))}async outerPosition(){return m("plugin:window|outer_position",{label:this.label}).then(({x:e,y:n})=>new it(e,n))}async innerSize(){return m("plugin:window|inner_size",{label:this.label}).then(({width:e,height:n})=>new ln(e,n))}async outerSize(){return m("plugin:window|outer_size",{label:this.label}).then(({width:e,height:n})=>new ln(e,n))}async isFullscreen(){return m("plugin:window|is_fullscreen",{label:this.label})}async isMinimized(){return m("plugin:window|is_minimized",{label:this.label})}async isMaximized(){return m("plugin:window|is_maximized",{label:this.label})}async isFocused(){return m("plugin:window|is_focused",{label:this.label})}async isDecorated(){return m("plugin:window|is_decorated",{label:this.label})}async isResizable(){return m("plugin:window|is_resizable",{label:this.label})}async isMaximizable(){return m("plugin:window|is_maximizable",{label:this.label})}async isMinimizable(){return m("plugin:window|is_minimizable",{label:this.label})}async isClosable(){return m("plugin:window|is_closable",{label:this.label})}async isVisible(){return m("plugin:window|is_visible",{label:this.label})}async title(){return m("plugin:window|title",{label:this.label})}async theme(){return m("plugin:window|theme",{label:this.label})}async center(){return m("plugin:window|center",{label:this.label})}async requestUserAttention(e){let n=null;return e&&(e===Ni.Critical?n={type:"Critical"}:n={type:"Informational"}),m("plugin:window|request_user_attention",{label:this.label,value:n})}async setResizable(e){return m("plugin:window|set_resizable",{label:this.label,value:e})}async setMaximizable(e){return m("plugin:window|set_maximizable",{label:this.label,value:e})}async setMinimizable(e){return m("plugin:window|set_minimizable",{label:this.label,value:e})}async setClosable(e){return m("plugin:window|set_closable",{label:this.label,value:e})}async setTitle(e){return m("plugin:window|set_title",{label:this.label,value:e})}async maximize(){return m("plugin:window|maximize",{label:this.label})}async unmaximize(){return m("plugin:window|unmaximize",{label:this.label})}async toggleMaximize(){return m("plugin:window|toggle_maximize",{label:this.label})}async minimize(){return m("plugin:window|minimize",{label:this.label})}async unminimize(){return m("plugin:window|unminimize",{label:this.label})}async show(){return m("plugin:window|show",{label:this.label})}async hide(){return m("plugin:window|hide",{label:this.label})}async close(){return m("plugin:window|close",{label:this.label})}async setDecorations(e){return m("plugin:window|set_decorations",{label:this.label,value:e})}async setShadow(e){return m("plugin:window|set_shadow",{label:this.label,value:e})}async setEffects(e){return m("plugin:window|set_effects",{label:this.label,value:e})}async clearEffects(){return m("plugin:window|set_effects",{label:this.label,value:null})}async setAlwaysOnTop(e){return m("plugin:window|set_always_on_top",{label:this.label,value:e})}async setAlwaysOnBottom(e){return m("plugin:window|set_always_on_bottom",{label:this.label,value:e})}async setContentProtected(e){return m("plugin:window|set_content_protected",{label:this.label,value:e})}async setSize(e){if(!e||e.type!=="Logical"&&e.type!=="Physical")throw new Error("the `size` argument must be either a LogicalSize or a PhysicalSize instance");return m("plugin:window|set_size",{label:this.label,value:{type:e.type,data:{width:e.width,height:e.height}}})}async setMinSize(e){if(e&&e.type!=="Logical"&&e.type!=="Physical")throw new Error("the `size` argument must be either a LogicalSize or a PhysicalSize instance");return m("plugin:window|set_min_size",{label:this.label,value:e?{type:e.type,data:{width:e.width,height:e.height}}:null})}async setMaxSize(e){if(e&&e.type!=="Logical"&&e.type!=="Physical")throw new Error("the `size` argument must be either a LogicalSize or a PhysicalSize instance");return m("plugin:window|set_max_size",{label:this.label,value:e?{type:e.type,data:{width:e.width,height:e.height}}:null})}async setPosition(e){if(!e||e.type!=="Logical"&&e.type!=="Physical")throw new Error("the `position` argument must be either a LogicalPosition or a PhysicalPosition instance");return m("plugin:window|set_position",{label:this.label,value:{type:e.type,data:{x:e.x,y:e.y}}})}async setFullscreen(e){return m("plugin:window|set_fullscreen",{label:this.label,value:e})}async setFocus(){return m("plugin:window|set_focus",{label:this.label})}async setIcon(e){return m("plugin:window|set_icon",{label:this.label,value:typeof e=="string"?e:Array.from(e)})}async setSkipTaskbar(e){return m("plugin:window|set_skip_taskbar",{label:this.label,value:e})}async setCursorGrab(e){return m("plugin:window|set_cursor_grab",{label:this.label,value:e})}async setCursorVisible(e){return m("plugin:window|set_cursor_visible",{label:this.label,value:e})}async setCursorIcon(e){return m("plugin:window|set_cursor_icon",{label:this.label,value:e})}async setCursorPosition(e){if(!e||e.type!=="Logical"&&e.type!=="Physical")throw new Error("the `position` argument must be either a LogicalPosition or a PhysicalPosition instance");return m("plugin:window|set_cursor_position",{label:this.label,value:{type:e.type,data:{x:e.x,y:e.y}}})}async setIgnoreCursorEvents(e){return m("plugin:window|set_ignore_cursor_events",{label:this.label,value:e})}async startDragging(){return m("plugin:window|start_dragging",{label:this.label})}async setProgressBar(e){return m("plugin:window|set_progress_bar",{label:this.label,value:e})}async onResized(e){return this.listen(ze.WINDOW_RESIZED,n=>{n.payload=$r(n.payload),e(n)})}async onMoved(e){return this.listen(ze.WINDOW_MOVED,n=>{n.payload=yl(n.payload),e(n)})}async onCloseRequested(e){return this.listen(ze.WINDOW_CLOSE_REQUESTED,n=>{const l=new Zr(n);Promise.resolve(e(l)).then(()=>{if(!l.isPreventDefault())return this.close()})})}async onFocusChanged(e){const n=await this.listen(ze.WINDOW_FOCUS,s=>{e({...s,payload:!0})}),l=await this.listen(ze.WINDOW_BLUR,s=>{e({...s,payload:!1})});return()=>{n(),l()}}async onScaleChanged(e){return this.listen(ze.WINDOW_SCALE_FACTOR_CHANGED,e)}async onFileDropEvent(e){const n=await this.listen(ze.WINDOW_FILE_DROP,u=>{e({...u,payload:{type:"drop",paths:u.payload.paths,position:yl(u.payload.position)}})}),l=await this.listen(ze.WINDOW_FILE_DROP_HOVER,u=>{e({...u,payload:{type:"hover",paths:u.payload.paths,position:yl(u.payload.position)}})}),s=await this.listen(ze.WINDOW_FILE_DROP_CANCELLED,u=>{e({...u,payload:{type:"cancel"}})});return()=>{n(),l(),s()}}async onThemeChanged(e){return this.listen(ze.WINDOW_THEME_CHANGED,e)}}var Gi;(function(t){t.AppearanceBased="appearanceBased",t.Light="light",t.Dark="dark",t.MediumLight="mediumLight",t.UltraDark="ultraDark",t.Titlebar="titlebar",t.Selection="selection",t.Menu="menu",t.Popover="popover",t.Sidebar="sidebar",t.HeaderView="headerView",t.Sheet="sheet",t.WindowBackground="windowBackground",t.HudWindow="hudWindow",t.FullScreenUI="fullScreenUI",t.Tooltip="tooltip",t.ContentBackground="contentBackground",t.UnderWindowBackground="underWindowBackground",t.UnderPageBackground="underPageBackground",t.Mica="mica",t.Blur="blur",t.Acrylic="acrylic",t.Tabbed="tabbed",t.TabbedDark="tabbedDark",t.TabbedLight="tabbedLight"})(Gi||(Gi={}));var Ki;(function(t){t.FollowsWindowActiveState="followsWindowActiveState",t.Active="active",t.Inactive="inactive"})(Ki||(Ki={}));function yl(t){return new it(t.x,t.y)}function $r(t){return new ln(t.width,t.height)}function Ms(t,e,n){const l=t.slice();return l[105]=e[n],l}function Ls(t,e,n){const l=t.slice();return l[108]=e[n],l}function Ps(t,e,n){const l=t.slice();return l[111]=e[n],l}function As(t,e,n){const l=t.slice();return l[114]=e[n],l}function Es(t,e,n){const l=t.slice();return l[117]=e[n],l}function Is(t){let e,n,l,s,u,d,o=he(Object.keys(t[1])),c=[];for(let h=0;ht[59].call(l))},m(h,k){S(h,e,k),S(h,n,k),S(h,l,k),i(l,s);for(let b=0;bt[83].call(tt)),a(pt,"class","input"),a(pt,"type","number"),a(mt,"class","input"),a(mt,"type","number"),a(et,"class","flex gap-2"),a(gt,"class","input grow"),a(gt,"id","title"),a(Sn,"class","btn"),a(Sn,"type","submit"),a(Et,"class","flex gap-1"),a(Cn,"class","flex flex-col gap-1"),a(nt,"class","input"),t[26]===void 0&&wt(()=>t[87].call(nt)),a(Ye,"class","input"),a(Ye,"type","number"),a(Ye,"min","0"),a(Ye,"max","100"),a(Qt,"class","flex gap-2"),a(Mn,"class","flex flex-col gap-1")},m(f,g){S(f,e,g),S(f,n,g),S(f,l,g),i(l,s),i(l,u),i(l,d),i(d,o),z(o,t[43]),i(d,c),i(d,h),S(f,k,g),S(f,b,g),S(f,O,g),S(f,_,g),i(_,P),i(_,v),i(_,E),i(_,V),i(_,D),i(_,L),i(_,W),S(f,A,g),S(f,I,g),i(I,R),i(R,Y),i(R,q),q.checked=t[6],i(I,Q),i(I,ie),i(ie,ee),i(ie,y),y.checked=t[2],i(I,B),i(I,G),i(G,oe),i(G,Z),Z.checked=t[3],i(I,we),i(I,be),i(be,fe),i(be,ce),ce.checked=t[4],i(I,$),i(I,pe),i(pe,K),i(pe,le),le.checked=t[5],i(I,te),i(I,T),i(T,J),i(T,H),H.checked=t[7],i(I,re),i(I,Le),i(Le,ke),i(Le,me),me.checked=t[8],i(I,Oe),i(I,Pe),i(Pe,We),i(Pe,ge),ge.checked=t[9],i(I,_e),i(I,Se),i(Se,Ae),i(Se,de),de.checked=t[10],i(I,Me),i(I,ae),i(ae,Re),i(ae,De),De.checked=t[11],S(f,Ee,g),S(f,ue,g),S(f,F,g),S(f,x,g),i(x,U),i(U,Ie),i(Ie,Dn),i(Ie,Fe),z(Fe,t[18]),i(U,Fn),i(U,zt),i(zt,Hn),i(zt,He),z(He,t[19]),i(x,Un),i(x,lt),i(lt,Ot),i(Ot,Bn),i(Ot,Ue),z(Ue,t[12]),i(lt,Vn),i(lt,Wt),i(Wt,qn),i(Wt,Be),z(Be,t[13]),i(x,Nn),i(x,st),i(st,Rt),i(Rt,jn),i(Rt,Ge),z(Ge,t[14]),i(st,Gn),i(st,Dt),i(Dt,Kn),i(Dt,Ke),z(Ke,t[15]),i(x,Xn),i(x,rt),i(rt,Ft),i(Ft,Yn),i(Ft,Ve),z(Ve,t[16]),i(rt,Qn),i(rt,Ht),i(Ht,Jn),i(Ht,qe),z(qe,t[17]),S(f,cn,g),S(f,dn,g),S(f,hn,g),S(f,Te,g),i(Te,at),i(at,Xe),i(Xe,N),i(Xe,fn),i(Xe,kt),i(kt,pn),i(kt,Ut),i(Xe,mn),i(Xe,vt),i(vt,gn),i(vt,Bt),i(at,_n),i(at,Ne),i(Ne,St),i(Ne,bn),i(Ne,Mt),i(Mt,wn),i(Mt,Vt),i(Ne,kn),i(Ne,Pt),i(Pt,yn),i(Pt,qt),i(Te,Zn),i(Te,Nt),i(Nt,ut),i(ut,$n),i(ut,Tl),i(ut,xn),i(xn,zl),i(xn,Xi),i(ut,Ol),i(ut,ti),i(ti,Wl),i(ti,Yi),i(Nt,Rl),i(Nt,ot),i(ot,ii),i(ot,Dl),i(ot,li),i(li,Fl),i(li,Qi),i(ot,Hl),i(ot,ri),i(ri,Ul),i(ri,Ji),i(Te,Bl),i(Te,jt),i(jt,ct),i(ct,ui),i(ct,Vl),i(ct,oi),i(oi,ql),i(oi,Zi),i(ct,Nl),i(ct,di),i(di,jl),i(di,$i),i(jt,Gl),i(jt,dt),i(dt,fi),i(dt,Kl),i(dt,pi),i(pi,Xl),i(pi,xi),i(dt,Yl),i(dt,gi),i(gi,Ql),i(gi,el),i(Te,Jl),i(Te,Gt),i(Gt,ht),i(ht,bi),i(ht,Zl),i(ht,wi),i(wi,$l),i(wi,tl),i(ht,xl),i(ht,yi),i(yi,es),i(yi,nl),i(Gt,ts),i(Gt,ft),i(ft,Ci),i(ft,ns),i(ft,Si),i(Si,is),i(Si,il),i(ft,ls),i(ft,Li),i(Li,ss),i(Li,ll),S(f,sl,g),S(f,rl,g),S(f,al,g),S(f,vn,g),S(f,ul,g),S(f,xe,g),i(xe,Ai),i(Ai,Kt),Kt.checked=t[20],i(Ai,rs),i(xe,as),i(xe,Ei),i(Ei,Xt),Xt.checked=t[21],i(Ei,us),i(xe,os),i(xe,Ii),i(Ii,Yt),Yt.checked=t[25],i(Ii,cs),S(f,ol,g),S(f,et,g),i(et,Ti),i(Ti,ds),i(Ti,tt);for(let j=0;jt[89].call(u)),a(h,"class","input"),t[37]===void 0&&wt(()=>t[90].call(h)),a(_,"class","input"),a(_,"type","number"),a(n,"class","flex"),$t(L,"max-width","120px"),a(L,"class","input"),a(L,"type","number"),a(L,"placeholder","R"),$t(A,"max-width","120px"),a(A,"class","input"),a(A,"type","number"),a(A,"placeholder","G"),$t(R,"max-width","120px"),a(R,"class","input"),a(R,"type","number"),a(R,"placeholder","B"),$t(q,"max-width","120px"),a(q,"class","input"),a(q,"type","number"),a(q,"placeholder","A"),a(D,"class","flex"),a(v,"class","flex"),a(ee,"class","btn"),$t(ee,"width","80px"),a(ie,"class","flex"),a(fe,"class","btn"),$t(fe,"width","80px"),a(B,"class","flex"),a(e,"class","flex flex-col gap-1")},m(T,J){S(T,e,J),i(e,n),i(n,l),i(l,s),i(l,u);for(let H=0;H=1,k,b,O,_=h&&Is(t),P=t[1][t[0]]&&zs(t);return{c(){e=r("div"),n=r("div"),l=r("input"),s=p(),u=r("button"),u.textContent="New window",d=p(),o=r("br"),c=p(),_&&_.c(),k=p(),P&&P.c(),a(l,"class","input grow"),a(l,"type","text"),a(l,"placeholder","New Window label.."),a(u,"class","btn"),a(n,"class","flex gap-1"),a(e,"class","flex flex-col children:grow gap-2")},m(v,E){S(v,e,E),i(e,n),i(n,l),z(l,t[28]),i(n,s),i(n,u),i(e,d),i(e,o),i(e,c),_&&_.m(e,null),i(e,k),P&&P.m(e,null),b||(O=[M(l,"input",t[58]),M(u,"click",t[53])],b=!0)},p(v,E){E[0]&268435456&&l.value!==v[28]&&z(l,v[28]),E[0]&2&&(h=Object.keys(v[1]).length>=1),h?_?_.p(v,E):(_=Is(v),_.c(),_.m(e,k)):_&&(_.d(1),_=null),v[1][v[0]]?P?P.p(v,E):(P=zs(v),P.c(),P.m(e,null)):P&&(P.d(1),P=null)},i:ne,o:ne,d(v){v&&C(e),_&&_.d(),P&&P.d(),b=!1,Ce(O)}}}function ta(t,e,n){const l=or();let s=l.label;const u={[l.label]:l},d=["default","crosshair","hand","arrow","move","text","wait","help","progress","notAllowed","contextMenu","cell","verticalText","alias","copy","noDrop","grab","grabbing","allScroll","zoomIn","zoomOut","eResize","nResize","neResize","nwResize","sResize","seResize","swResize","wResize","ewResize","nsResize","neswResize","nwseResize","colResize","rowResize"],o=["mica","blur","acrylic","tabbed","tabbedDark","tabbedLight"],c=navigator.appVersion.includes("Windows"),h=navigator.appVersion.includes("Macintosh");let k=c?o:Object.keys(Gi).map(N=>Gi[N]).filter(N=>!o.includes(N));const b=Object.keys(Ki).map(N=>Ki[N]),O=Object.keys(ji).map(N=>ji[N]);let{onMessage:_}=e;const P=document.querySelector("main");let v,E=!0,V=!0,D=!0,L=!0,W=!1,A=!0,I=!1,R=!1,Y=!0,q=!1,Q=null,ie=null,ee=null,y=null,B=null,G=null,oe=null,Z=null,we=1,be=new it(oe,Z),fe=new it(oe,Z),ce=new ln(Q,ie),$=new ln(Q,ie),pe,K,le=!1,te=!0,T=null,J=null,H="default",re=!1,Le="Awesome Tauri Example!",ke=[],me,Oe,Pe,We,ge,_e,Se,Ae="none",de=0,Me;function ae(){u[s].setTitle(Le)}function Re(){u[s].hide(),setTimeout(u[s].show,2e3)}function De(){u[s].minimize(),setTimeout(u[s].unminimize,2e3)}function Ee(){if(!v)return;const N=new Rn(v);n(1,u[v]=N,u),N.once("tauri://error",function(){_("Error creating new webview")})}function ue(){u[s].innerSize().then(N=>{n(32,ce=N),n(12,Q=ce.width),n(13,ie=ce.height)}),u[s].outerSize().then(N=>{n(33,$=N)})}function F(){u[s].innerPosition().then(N=>{n(30,be=N)}),u[s].outerPosition().then(N=>{n(31,fe=N),n(18,oe=fe.x),n(19,Z=fe.y)})}async function x(N){N&&(pe&&pe(),K&&K(),K=await N.listen("tauri://move",F),pe=await N.listen("tauri://resize",ue))}async function U(){await u[s].minimize(),await u[s].requestUserAttention(Ni.Critical),await new Promise(N=>setTimeout(N,3e3)),await u[s].requestUserAttention(null)}async function Ie(){ke.includes(me)||n(35,ke=[...ke,me]);const N={effects:ke,state:Oe,radius:Pe};Number.isInteger(We)&&Number.isInteger(ge)&&Number.isInteger(_e)&&Number.isInteger(Se)&&(N.color=[We,ge,_e,Se]),P.classList.remove("bg-primary"),P.classList.remove("dark:bg-darkPrimary"),await u[s].clearEffects(),await u[s].setEffects(N)}async function Dn(){n(35,ke=[]),await u[s].clearEffects(),P.classList.add("bg-primary"),P.classList.add("dark:bg-darkPrimary")}function Fe(){v=this.value,n(28,v)}function Fn(){s=Pn(this),n(0,s),n(1,u)}function zt(){Me=this.value,n(43,Me)}const Hn=()=>u[s].center();function He(){W=this.checked,n(6,W)}function Un(){E=this.checked,n(2,E)}function lt(){V=this.checked,n(3,V)}function Ot(){D=this.checked,n(4,D)}function Bn(){L=this.checked,n(5,L)}function Ue(){A=this.checked,n(7,A)}function Vn(){I=this.checked,n(8,I)}function Wt(){R=this.checked,n(9,R)}function qn(){Y=this.checked,n(10,Y)}function Be(){q=this.checked,n(11,q)}function Nn(){oe=X(this.value),n(18,oe)}function st(){Z=X(this.value),n(19,Z)}function Rt(){Q=X(this.value),n(12,Q)}function jn(){ie=X(this.value),n(13,ie)}function Ge(){ee=X(this.value),n(14,ee)}function Gn(){y=X(this.value),n(15,y)}function Dt(){B=X(this.value),n(16,B)}function Kn(){G=X(this.value),n(17,G)}function Ke(){le=this.checked,n(20,le)}function Xn(){te=this.checked,n(21,te)}function rt(){re=this.checked,n(25,re)}function Ft(){H=Pn(this),n(24,H),n(44,d)}function Yn(){T=X(this.value),n(22,T)}function Ve(){J=X(this.value),n(23,J)}function Qn(){Le=this.value,n(34,Le)}function Ht(){Ae=Pn(this),n(26,Ae),n(49,O)}function Jn(){de=X(this.value),n(27,de)}function qe(){me=Pn(this),n(36,me),n(47,k)}function cn(){Oe=Pn(this),n(37,Oe),n(48,b)}function dn(){Pe=X(this.value),n(38,Pe)}function hn(){We=X(this.value),n(39,We)}function Te(){ge=X(this.value),n(40,ge)}function at(){_e=X(this.value),n(41,_e)}function Xe(){Se=X(this.value),n(42,Se)}return t.$$set=N=>{"onMessage"in N&&n(57,_=N.onMessage)},t.$$.update=()=>{var N,fn,kt,pn,yt,Ut,mn,vt,gn,Ct,Bt,_n,Ne,St,bn,Mt,wn,Lt,Vt,kn,Pt,yn,At,qt;t.$$.dirty[0]&3&&(u[s],F(),ue()),t.$$.dirty[0]&7&&((N=u[s])==null||N.setResizable(E)),t.$$.dirty[0]&11&&((fn=u[s])==null||fn.setMaximizable(V)),t.$$.dirty[0]&19&&((kt=u[s])==null||kt.setMinimizable(D)),t.$$.dirty[0]&35&&((pn=u[s])==null||pn.setClosable(L)),t.$$.dirty[0]&67&&(W?(yt=u[s])==null||yt.maximize():(Ut=u[s])==null||Ut.unmaximize()),t.$$.dirty[0]&131&&((mn=u[s])==null||mn.setDecorations(A)),t.$$.dirty[0]&259&&((vt=u[s])==null||vt.setAlwaysOnTop(I)),t.$$.dirty[0]&515&&((gn=u[s])==null||gn.setAlwaysOnBottom(R)),t.$$.dirty[0]&1027&&((Ct=u[s])==null||Ct.setContentProtected(Y)),t.$$.dirty[0]&2051&&((Bt=u[s])==null||Bt.setFullscreen(q)),t.$$.dirty[0]&12291&&Q&&ie&&((_n=u[s])==null||_n.setSize(new ln(Q,ie))),t.$$.dirty[0]&49155&&(ee&&y?(Ne=u[s])==null||Ne.setMinSize(new Ll(ee,y)):(St=u[s])==null||St.setMinSize(null)),t.$$.dirty[0]&196611&&(B>800&&G>400?(bn=u[s])==null||bn.setMaxSize(new Ll(B,G)):(Mt=u[s])==null||Mt.setMaxSize(null)),t.$$.dirty[0]&786435&&oe!==null&&Z!==null&&((wn=u[s])==null||wn.setPosition(new it(oe,Z))),t.$$.dirty[0]&3&&((Lt=u[s])==null||Lt.scaleFactor().then(Zn=>n(29,we=Zn))),t.$$.dirty[0]&3&&x(u[s]),t.$$.dirty[0]&1048579&&((Vt=u[s])==null||Vt.setCursorGrab(le)),t.$$.dirty[0]&2097155&&((kn=u[s])==null||kn.setCursorVisible(te)),t.$$.dirty[0]&16777219&&((Pt=u[s])==null||Pt.setCursorIcon(H)),t.$$.dirty[0]&12582915&&T!==null&&J!==null&&((yn=u[s])==null||yn.setCursorPosition(new it(T,J))),t.$$.dirty[0]&33554435&&((At=u[s])==null||At.setIgnoreCursorEvents(re)),t.$$.dirty[0]&201326595&&((qt=u[s])==null||qt.setProgressBar({status:Ae,progress:de}))},[s,u,E,V,D,L,W,A,I,R,Y,q,Q,ie,ee,y,B,G,oe,Z,le,te,T,J,H,re,Ae,de,v,we,be,fe,ce,$,Le,ke,me,Oe,Pe,We,ge,_e,Se,Me,d,c,h,k,b,O,ae,Re,De,Ee,U,Ie,Dn,_,Fe,Fn,zt,Hn,He,Un,lt,Ot,Bn,Ue,Vn,Wt,qn,Be,Nn,st,Rt,jn,Ge,Gn,Dt,Kn,Ke,Xn,rt,Ft,Yn,Ve,Qn,Ht,Jn,qe,cn,dn,hn,Te,at,Xe]}class na extends $e{constructor(e){super(),Ze(this,e,ta,ea,je,{onMessage:57},null,[-1,-1,-1,-1])}}function ia(t){let e;return{c(){e=r("div"),e.innerHTML='
Not available for Linux
',a(e,"class","flex flex-col gap-2")},m(n,l){S(n,e,l)},p:ne,i:ne,o:ne,d(n){n&&C(e)}}}function la(t,e,n){let{onMessage:l}=e;const s=window.constraints={audio:!0,video:!0};function u(o){const c=document.querySelector("video"),h=o.getVideoTracks();l("Got stream with constraints:",s),l(`Using video device: ${h[0].label}`),window.stream=o,c.srcObject=o}function d(o){if(o.name==="ConstraintNotSatisfiedError"){const c=s.video;l(`The resolution ${c.width.exact}x${c.height.exact} px is not supported by your device.`)}else o.name==="PermissionDeniedError"&&l("Permissions have not been granted to use your camera and microphone, you need to allow the page access to your devices in order for the demo to work.");l(`getUserMedia error: ${o.name}`,o)}return Vi(async()=>{try{const o=await navigator.mediaDevices.getUserMedia(s);u(o)}catch(o){d(o)}}),er(()=>{var o;(o=window.stream)==null||o.getTracks().forEach(function(c){c.stop()})}),t.$$set=o=>{"onMessage"in o&&n(0,l=o.onMessage)},[l]}class sa extends $e{constructor(e){super(),Ze(this,e,la,ia,je,{onMessage:0})}}function ra(t){let e,n,l,s,u,d;return{c(){e=r("div"),n=r("button"),n.textContent="Show",l=p(),s=r("button"),s.textContent="Hide",a(n,"class","btn"),a(n,"id","show"),a(n,"title","Hides and shows the app after 2 seconds"),a(s,"class","btn"),a(s,"id","hide")},m(o,c){S(o,e,c),i(e,n),i(e,l),i(e,s),u||(d=[M(n,"click",t[0]),M(s,"click",t[1])],u=!0)},p:ne,i:ne,o:ne,d(o){o&&C(e),u=!1,Ce(d)}}}function aa(t,e,n){let{onMessage:l}=e;function s(){u().then(()=>{setTimeout(()=>{Vr().then(()=>l("Shown app")).catch(l)},2e3)}).catch(l)}function u(){return qr().then(()=>l("Hide app")).catch(l)}return t.$$set=d=>{"onMessage"in d&&n(2,l=d.onMessage)},[s,u,l]}class ua extends $e{constructor(e){super(),Ze(this,e,aa,ra,je,{onMessage:2})}}var Hi;class cr{get rid(){return Wn(this,Hi,"f")}constructor(e){Hi.set(this,void 0),qi(this,Hi,e,"f")}async close(){return m("plugin:resources|close",{rid:this.rid})}}Hi=new WeakMap;var Ui,Bi;async function un(t,e){const n=new rr;let l=null;return e&&typeof e=="object"&&("action"in e&&e.action&&(n.onmessage=e.action,delete e.action),"items"in e&&e.items&&(l=e.items.map(s=>[s.rid,s.kind]))),m("plugin:menu|new",{kind:t,options:e?{...e,items:l}:void 0,handler:n})}class on extends cr{get id(){return Wn(this,Ui,"f")}get kind(){return Wn(this,Bi,"f")}constructor(e,n,l){super(e),Ui.set(this,void 0),Bi.set(this,void 0),qi(this,Ui,n,"f"),qi(this,Bi,l,"f")}}Ui=new WeakMap,Bi=new WeakMap;function vl([t,e,n]){switch(n){case"Submenu":return new dr(t,e);case"Predefined":return new PredefinedMenuItem(t,e);case"Check":return new CheckMenuItem(t,e);case"Icon":return new IconMenuItem(t,e);case"MenuItem":default:return new MenuItem(t,e)}}let dr=class hr extends on{constructor(e,n){super(e,n,"Submenu")}static async new(e){return un("Submenu",e).then(([n,l])=>new hr(n,l))}async text(){return m("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return m("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return m("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return m("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async append(e){return m("plugin:menu|append",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map(n=>[n.rid,n.kind])})}async prepend(e){return m("plugin:menu|prepend",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map(n=>[n.rid,n.kind])})}async insert(e,n){return m("plugin:menu|insert",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map(l=>[l.rid,l.kind]),position:n})}async remove(e){return m("plugin:menu|remove",{rid:this.rid,kind:this.kind,item:[e.rid,e.kind]})}async removeAt(e){return m("plugin:menu|remove_at",{rid:this.rid,kind:this.kind,position:e}).then(vl)}async items(){return m("plugin:menu|append",{rid:this.rid,kind:this.kind}).then(e=>e.map(vl))}async get(e){return m("plugin:menu|append",{rid:this.rid,kind:this.kind,id:e}).then(n=>n?vl(n):null)}async popup(e,n){let l=null;return e&&(l={type:e instanceof it?"Physical":"Logical",data:e}),m("plugin:menu|popup",{rid:this.rid,kind:this.kind,window:(n==null?void 0:n.label)??null,at:l})}async setAsWindowsMenuForNSApp(){return m("plugin:menu|set_as_windows_menu_for_nsapp",{rid:this.rid})}async setAsHelpMenuForNSApp(){return m("plugin:menu|set_as_help_menu_for_nsapp",{rid:this.rid})}},oa=class fr extends on{constructor(e,n){super(e,n,"MenuItem")}static async new(e){return un("MenuItem",e).then(([n,l])=>new fr(n,l))}async text(){return m("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return m("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return m("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return m("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return m("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}};function Cl([t,e,n]){switch(n){case"Submenu":return new Submenu(t,e);case"Predefined":return new PredefinedMenuItem(t,e);case"Check":return new CheckMenuItem(t,e);case"Icon":return new IconMenuItem(t,e);case"MenuItem":default:return new MenuItem(t,e)}}class bt extends on{constructor(e,n){super(e,n,"Menu")}static async new(e){return un("Menu",e).then(([n,l])=>new bt(n,l))}static async default(){return m("plugin:menu|default").then(([e,n])=>new bt(e,n))}async append(e){return m("plugin:menu|append",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map(n=>[n.rid,n.kind])})}async prepend(e){return m("plugin:menu|prepend",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map(n=>[n.rid,n.kind])})}async insert(e,n){return m("plugin:menu|insert",{rid:this.rid,kind:this.kind,items:(Array.isArray(e)?e:[e]).map(l=>[l.rid,l.kind]),position:n})}async remove(e){return m("plugin:menu|remove",{rid:this.rid,kind:this.kind,item:[e.rid,e.kind]})}async removeAt(e){return m("plugin:menu|remove_at",{rid:this.rid,kind:this.kind,position:e}).then(Cl)}async items(){return m("plugin:menu|append",{rid:this.rid,kind:this.kind}).then(e=>e.map(Cl))}async get(e){return m("plugin:menu|append",{rid:this.rid,kind:this.kind,id:e}).then(n=>n?Cl(n):null)}async popup(e,n){let l=null;return e&&(l={type:e instanceof it?"Physical":"Logical",data:e}),m("plugin:menu|popup",{rid:this.rid,kind:this.kind,window:(n==null?void 0:n.label)??null,at:l})}async setAsAppMenu(){return m("plugin:menu|set_as_app_menu",{rid:this.rid}).then(e=>e?new bt(e[0],e[1]):null)}async setAsWindowMenu(e){return m("plugin:menu|set_as_window_menu",{rid:this.rid,window:(e==null?void 0:e.label)??null}).then(n=>n?new bt(n[0],n[1]):null)}}let pr=class mr extends on{constructor(e,n){super(e,n,"Check")}static async new(e){return un("Check",e).then(([n,l])=>new mr(n,l))}async text(){return m("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return m("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return m("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return m("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return m("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}async isChecked(){return m("plugin:menu|is_checked",{rid:this.rid})}async setChecked(e){return m("plugin:menu|set_checked",{rid:this.rid,checked:e})}};var Fs;(function(t){t.Add="Add",t.Advanced="Advanced",t.Bluetooth="Bluetooth",t.Bookmarks="Bookmarks",t.Caution="Caution",t.ColorPanel="ColorPanel",t.ColumnView="ColumnView",t.Computer="Computer",t.EnterFullScreen="EnterFullScreen",t.Everyone="Everyone",t.ExitFullScreen="ExitFullScreen",t.FlowView="FlowView",t.Folder="Folder",t.FolderBurnable="FolderBurnable",t.FolderSmart="FolderSmart",t.FollowLinkFreestanding="FollowLinkFreestanding",t.FontPanel="FontPanel",t.GoLeft="GoLeft",t.GoRight="GoRight",t.Home="Home",t.IChatTheater="IChatTheater",t.IconView="IconView",t.Info="Info",t.InvalidDataFreestanding="InvalidDataFreestanding",t.LeftFacingTriangle="LeftFacingTriangle",t.ListView="ListView",t.LockLocked="LockLocked",t.LockUnlocked="LockUnlocked",t.MenuMixedState="MenuMixedState",t.MenuOnState="MenuOnState",t.MobileMe="MobileMe",t.MultipleDocuments="MultipleDocuments",t.Network="Network",t.Path="Path",t.PreferencesGeneral="PreferencesGeneral",t.QuickLook="QuickLook",t.RefreshFreestanding="RefreshFreestanding",t.Refresh="Refresh",t.Remove="Remove",t.RevealFreestanding="RevealFreestanding",t.RightFacingTriangle="RightFacingTriangle",t.Share="Share",t.Slideshow="Slideshow",t.SmartBadge="SmartBadge",t.StatusAvailable="StatusAvailable",t.StatusNone="StatusNone",t.StatusPartiallyAvailable="StatusPartiallyAvailable",t.StatusUnavailable="StatusUnavailable",t.StopProgressFreestanding="StopProgressFreestanding",t.StopProgress="StopProgress",t.TrashEmpty="TrashEmpty",t.TrashFull="TrashFull",t.User="User",t.UserAccounts="UserAccounts",t.UserGroup="UserGroup",t.UserGuest="UserGuest"})(Fs||(Fs={}));let ca=class gr extends on{constructor(e,n){super(e,n,"Icon")}static async new(e){return un("Icon",e).then(([n,l])=>new gr(n,l))}async text(){return m("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return m("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}async isEnabled(){return m("plugin:menu|is_enabled",{rid:this.rid,kind:this.kind})}async setEnabled(e){return m("plugin:menu|set_enabled",{rid:this.rid,kind:this.kind,enabled:e})}async setAccelerator(e){return m("plugin:menu|set_accelerator",{rid:this.rid,kind:this.kind,accelerator:e})}async setIcon(e){return m("plugin:menu|set_icon",{rid:this.rid,icon:e})}async setNativeIcon(e){return m("plugin:menu|set_native_icon",{rid:this.rid,icon:e})}},da=class _r extends on{constructor(e,n){super(e,n,"Predefined")}static async new(e){return un("Predefined",e).then(([n,l])=>new _r(n,l))}async text(){return m("plugin:menu|text",{rid:this.rid,kind:this.kind})}async setText(e){return m("plugin:menu|set_text",{rid:this.rid,kind:this.kind,text:e})}};function Hs(t,e,n){const l=t.slice();return l[16]=e[n],l[17]=e,l[18]=n,l}function Us(t,e,n){const l=t.slice();return l[19]=e[n],l[20]=e,l[21]=n,l}function Bs(t){let e,n,l,s,u,d,o=t[19]+"",c,h,k,b,O;function _(){t[9].call(n,t[20],t[21])}return{c(){e=r("div"),n=r("input"),u=p(),d=r("label"),c=w(o),k=p(),a(n,"id",l=t[19]+"Input"),n.checked=s=t[0]===t[19],a(n,"type","radio"),a(n,"name","kind"),a(d,"for",h=t[19]+"Input"),a(e,"class","flex gap-1")},m(P,v){S(P,e,v),i(e,n),z(n,t[19]),i(e,u),i(e,d),i(d,c),i(e,k),b||(O=[M(n,"change",t[6]),M(n,"change",_)],b=!0)},p(P,v){t=P,v&16&&l!==(l=t[19]+"Input")&&a(n,"id",l),v&17&&s!==(s=t[0]===t[19])&&(n.checked=s),v&16&&z(n,t[19]),v&16&&o!==(o=t[19]+"")&&se(c,o),v&16&&h!==(h=t[19]+"Input")&&a(d,"for",h)},d(P){P&&C(e),b=!1,Ce(O)}}}function Vs(t){let e,n,l;return{c(){e=r("input"),a(e,"class","input"),a(e,"type","text"),a(e,"placeholder","Text")},m(s,u){S(s,e,u),z(e,t[1]),n||(l=M(e,"input",t[10]),n=!0)},p(s,u){u&2&&e.value!==s[1]&&z(e,s[1])},d(s){s&&C(e),n=!1,l()}}}function ha(t){let e,n=he(t[5]),l=[];for(let s=0;sl("itemClick",{id:I,text:A})},W=await oa.new(L);break;case"Icon":L={text:u,icon:d,action:I=>l("itemClick",{id:I,text:A})},W=await ca.new(L);break;case"Check":L={text:u,checked:c,action:I=>l("itemClick",{id:I,text:A})},W=await pr.new(L);break;case"Predefined":L={item:o},W=await da.new(L);break}l("new",{item:W,options:L}),n(1,u=""),o=""}function P(L,W){L[W]=this.value,n(4,h)}function v(){u=this.value,n(1,u)}function E(){d=this.value,n(2,d)}function V(){c=this.checked,n(3,c)}function D(L,W){L[W]=this.value,n(5,k)}return[s,u,d,c,h,k,b,O,_,P,v,E,V,D]}class _a extends $e{constructor(e){super(),Ze(this,e,ga,ma,je,{})}}function Ns(t,e,n){const l=t.slice();return l[5]=e[n],l}function js(t){let e,n,l,s,u,d=Gs(t[5])+"",o,c;return{c(){e=r("div"),n=r("div"),s=p(),u=r("p"),o=w(d),c=p(),a(n,"class",l=t[3](t[5])),a(e,"class","flex flex-row gap-1")},m(h,k){S(h,e,k),i(e,n),i(e,s),i(e,u),i(u,o),i(e,c)},p(h,k){k&1&&l!==(l=h[3](h[5]))&&a(n,"class",l),k&1&&d!==(d=Gs(h[5])+"")&&se(o,d)},d(h){h&&C(e)}}}function ba(t){let e,n,l,s,u;n=new _a({}),n.$on("new",t[1]),n.$on("itemClick",t[2]);let d=he(t[0]),o=[];for(let c=0;c{"items"in c&&n(0,l=c.items)},[l,u,d,o]}class br extends $e{constructor(e){super(),Ze(this,e,wa,ba,je,{items:0})}}function ka(t){let e,n,l,s,u,d,o,c,h,k;function b(_){t[5](_)}let O={};return t[0]!==void 0&&(O.items=t[0]),n=new br({props:O}),Tn.push(()=>lr(n,"items",b)),n.$on("itemClick",t[3]),{c(){e=r("div"),On(n.$$.fragment),s=p(),u=r("button"),u.textContent="Create menu",d=p(),o=r("button"),o.textContent="Popup",a(u,"class","btn"),a(o,"class","btn")},m(_,P){S(_,e,P),rn(n,e,null),i(e,s),i(e,u),i(e,d),i(e,o),c=!0,h||(k=[M(u,"click",t[1]),M(o,"click",t[2])],h=!0)},p(_,[P]){const v={};!l&&P&1&&(l=!0,v.items=_[0],nr(()=>l=!1)),n.$set(v)},i(_){c||(sn(n.$$.fragment,_),c=!0)},o(_){zn(n.$$.fragment,_),c=!1},d(_){_&&C(e),an(n),h=!1,Ce(k)}}}function ya(t,e,n){let{onMessage:l}=e,s=[],u=null,d=null,o=0;const c=navigator.userAgent.includes("Macintosh");async function h(){d=await dr.new({text:"app",items:s.map(_=>_.item)}),o=s.length,u=await bt.new({items:[d]}),await(c?u.setAsAppMenu():u.setAsWindowMenu())}async function k(){(!d||o!==s.length)&&await h(),(await bt.new({items:[d]})).popup()}function b(_){l(`Item ${_.detail.text} clicked`)}function O(_){s=_,n(0,s)}return t.$$set=_=>{"onMessage"in _&&n(4,l=_.onMessage)},[s,h,k,b,l,O]}class va extends $e{constructor(e){super(),Ze(this,e,ya,ka,je,{onMessage:4})}}class Il extends cr{constructor(e,n){super(e),this.id=n}static async new(e){e!=null&&e.menu&&(e.menu=[e.menu.rid,e.menu.kind]),e!=null&&e.icon&&(e.icon=typeof e.icon=="string"?e.icon:Array.from(e.icon));const n=new rr;return e!=null&&e.action&&(n.onmessage=e.action,delete e.action),m("plugin:tray|new",{options:e??{},handler:n}).then(([l,s])=>new Il(l,s))}async setIcon(e){let n=null;return e&&(n=typeof e=="string"?e:Array.from(e)),m("plugin:tray|set_icon",{rid:this.rid,icon:n})}async setMenu(e){return e&&(e=[e.rid,e.kind]),m("plugin:tray|set_menu",{rid:this.rid,menu:e})}async setTooltip(e){return m("plugin:tray|set_tooltip",{rid:this.rid,tooltip:e})}async setTitle(e){return m("plugin:tray|set_title",{rid:this.rid,title:e})}async setVisible(e){return m("plugin:tray|set_visible",{rid:this.rid,visible:e})}async setTempDirPath(e){return m("plugin:tray|set_temp_dir_path",{rid:this.rid,path:e})}async setIconAsTemplate(e){return m("plugin:tray|set_icon_as_template",{rid:this.rid,asTemplate:e})}async setMenuOnLeftClick(e){return m("plugin:tray|set_show_menu_on_left_click",{rid:this.rid,onLeft:e})}}function Ca(t){let e,n,l,s,u,d,o,c,h,k,b,O,_,P,v,E,V,D,L,W,A,I,R,Y,q,Q;function ie(y){t[14](y)}let ee={};return t[5]!==void 0&&(ee.items=t[5]),L=new br({props:ee}),Tn.push(()=>lr(L,"items",ie)),L.$on("itemClick",t[6]),{c(){e=r("div"),n=r("div"),l=r("input"),s=p(),u=r("input"),d=p(),o=r("label"),c=w(`Menu on left click + `),h=r("input"),k=p(),b=r("div"),O=r("input"),_=p(),P=r("label"),v=w(`Icon as template + `),E=r("input"),V=p(),D=r("div"),On(L.$$.fragment),A=p(),I=r("div"),R=r("button"),R.textContent="Create tray",a(l,"class","input grow"),a(l,"type","text"),a(l,"placeholder","Title"),a(u,"class","input grow"),a(u,"type","text"),a(u,"placeholder","Tooltip"),a(h,"type","checkbox"),a(n,"class","flex gap-1"),a(O,"class","input grow"),a(O,"type","text"),a(O,"placeholder","Icon path"),a(E,"type","checkbox"),a(b,"class","flex gap-1"),a(D,"class","flex children:grow"),a(R,"class","btn"),a(R,"title","Creates the tray icon"),a(I,"class","flex"),a(e,"class","flex flex-col children:grow gap-2")},m(y,B){S(y,e,B),i(e,n),i(n,l),z(l,t[2]),i(n,s),i(n,u),z(u,t[1]),i(n,d),i(n,o),i(o,c),i(o,h),h.checked=t[4],i(e,k),i(e,b),i(b,O),z(O,t[0]),i(b,_),i(b,P),i(P,v),i(P,E),E.checked=t[3],i(e,V),i(e,D),rn(L,D,null),i(e,A),i(e,I),i(I,R),Y=!0,q||(Q=[M(l,"input",t[9]),M(u,"input",t[10]),M(h,"change",t[11]),M(O,"input",t[12]),M(E,"change",t[13]),M(R,"click",t[7])],q=!0)},p(y,[B]){B&4&&l.value!==y[2]&&z(l,y[2]),B&2&&u.value!==y[1]&&z(u,y[1]),B&16&&(h.checked=y[4]),B&1&&O.value!==y[0]&&z(O,y[0]),B&8&&(E.checked=y[3]);const G={};!W&&B&32&&(W=!0,G.items=y[5],nr(()=>W=!1)),L.$set(G)},i(y){Y||(sn(L.$$.fragment,y),Y=!0)},o(y){zn(L.$$.fragment,y),Y=!1},d(y){y&&C(e),an(L),q=!1,Ce(Q)}}}function Sa(t,e,n){let{onMessage:l}=e,s=null,u=null,d=null,o=!1,c=!0,h=[];function k(D){l(`Item ${D.detail.text} clicked`)}async function b(){Il.new({icon:s,tooltip:u,title:d,iconAsTemplate:o,menuOnLeftClick:c,menu:await bt.new({items:h.map(D=>D.item)}),action:D=>l(D)}).catch(l)}function O(){d=this.value,n(2,d)}function _(){u=this.value,n(1,u)}function P(){c=this.checked,n(4,c)}function v(){s=this.value,n(0,s)}function E(){o=this.checked,n(3,o)}function V(D){h=D,n(5,h)}return t.$$set=D=>{"onMessage"in D&&n(8,l=D.onMessage)},[s,u,d,o,c,h,k,b,l,O,_,P,v,E,V]}class Ma extends $e{constructor(e){super(),Ze(this,e,Sa,Ca,je,{onMessage:8})}}function Ks(t,e,n){const l=t.slice();return l[26]=e[n],l}function Xs(t,e,n){const l=t.slice();return l[29]=e[n],l}function La(t){let e;return{c(){e=r("span"),a(e,"class","i-codicon-menu animate-duration-300ms animate-fade-in")},m(n,l){S(n,e,l)},d(n){n&&C(e)}}}function Pa(t){let e;return{c(){e=r("span"),a(e,"class","i-codicon-close animate-duration-300ms animate-fade-in")},m(n,l){S(n,e,l)},d(n){n&&C(e)}}}function Aa(t){let e,n;return{c(){e=w(`Switch to Dark mode + `),n=r("div"),a(n,"class","i-ph-moon")},m(l,s){S(l,e,s),S(l,n,s)},d(l){l&&(C(e),C(n))}}}function Ea(t){let e,n;return{c(){e=w(`Switch to Light mode + `),n=r("div"),a(n,"class","i-ph-sun")},m(l,s){S(l,e,s),S(l,n,s)},d(l){l&&(C(e),C(n))}}}function Ia(t){let e,n,l,s,u,d,o;function c(){return t[14](t[29])}return{c(){e=r("a"),n=r("div"),l=p(),s=r("p"),s.textContent=`${t[29].label}`,a(n,"class",t[29].icon+" mr-2"),a(e,"href","##"),a(e,"class",u="nv "+(t[1]===t[29]?"nv_selected":""))},m(h,k){S(h,e,k),i(e,n),i(e,l),i(e,s),d||(o=M(e,"click",c),d=!0)},p(h,k){t=h,k[0]&2&&u!==(u="nv "+(t[1]===t[29]?"nv_selected":""))&&a(e,"class",u)},d(h){h&&C(e),d=!1,o()}}}function Ys(t){let e,n=t[29]&&Ia(t);return{c(){n&&n.c(),e=Pl()},m(l,s){n&&n.m(l,s),S(l,e,s)},p(l,s){l[29]&&n.p(l,s)},d(l){l&&C(e),n&&n.d(l)}}}function Qs(t){let e,n=t[26].html+"",l;return{c(){e=new Ar(!1),l=Pl(),e.a=l},m(s,u){e.m(n,s,u),S(s,l,u)},p(s,u){u[0]&16&&n!==(n=s[26].html+"")&&e.p(n)},d(s){s&&(C(l),e.d())}}}function Ta(t){let e,n,l,s,u,d,o,c,h,k,b,O,_,P,v,E,V,D,L,W,A,I,R,Y,q,Q,ie,ee,y,B,G,oe,Z=t[1].label+"",we,be,fe,ce,$,pe,K,le,te,T,J,H,re,Le,ke,me,Oe,Pe;function We(F,x){return F[0]?Pa:La}let ge=We(t),_e=ge(t);function Se(F,x){return F[2]?Ea:Aa}let Ae=Se(t),de=Ae(t),Me=he(t[5]),ae=[];for(let F=0;F`,V=p(),D=r("a"),D.innerHTML=`GitHub + `,L=p(),W=r("a"),W.innerHTML=`Source + `,A=p(),I=r("br"),R=p(),Y=r("div"),q=p(),Q=r("br"),ie=p(),ee=r("div");for(let F=0;F',Le=p(),ke=r("div");for(let F=0;F{an(U,1)}),Wr()}Re?($=Cs(Re,De(F)),On($.$$.fragment),sn($.$$.fragment,1),rn($,ce,null)):$=null}if(x[0]&16){Ee=he(F[4]);let U;for(U=0;U{y.ctrlKey&&y.key==="b"&&m("toggle_menu")});const s=navigator.userAgent.toLowerCase(),u=s.includes("android")||s.includes("iphone"),d=[{label:"Welcome",component:Gr,icon:"i-ph-hand-waving"},{label:"Communication",component:Qr,icon:"i-codicon-radio-tower"},!u&&{label:"App",component:ua,icon:"i-codicon-hubot"},{label:"Window",component:na,icon:"i-codicon-window"},{label:"Menu",component:va,icon:"i-ph-list"},{label:"Tray",component:Ma,icon:"i-ph-tray"},{label:"WebRTC",component:sa,icon:"i-ph-broadcast"}];let o=d[0];function c(y){n(1,o=y)}let h;Vi(()=>{n(2,h=localStorage&&localStorage.getItem("theme")=="dark"),Zs(h)});function k(){n(2,h=!h),Zs(h)}let b=Fr([]);Sr(t,b,y=>n(4,l=y));function O(y){b.update(B=>[{html:`
[${new Date().toLocaleTimeString()}]: `+(typeof y=="string"?y:JSON.stringify(y,null,1))+"
"},...B])}function _(y){b.update(B=>[{html:`
[${new Date().toLocaleTimeString()}]: `+y+"
"},...B])}function P(){b.update(()=>[])}let v,E,V;function D(y){V=y.clientY;const B=window.getComputedStyle(v);E=parseInt(B.height,10);const G=Z=>{const we=Z.clientY-V,be=E-we;n(3,v.style.height=`${be{document.removeEventListener("mouseup",oe),document.removeEventListener("mousemove",G)};document.addEventListener("mouseup",oe),document.addEventListener("mousemove",G)}let L=!1,W,A,I=!1,R=0,Y=0;const q=(y,B,G)=>Math.min(Math.max(B,y),G);Vi(()=>{n(13,W=document.querySelector("#sidebar")),A=document.querySelector("#sidebarToggle"),document.addEventListener("click",y=>{A.contains(y.target)?n(0,L=!L):L&&!W.contains(y.target)&&n(0,L=!1)}),document.addEventListener("touchstart",y=>{if(A.contains(y.target))return;const B=y.touches[0].clientX;(0{if(I){const B=y.touches[0].clientX;Y=B;const G=(B-R)/10;W.style.setProperty("--translate-x",`-${q(0,L?0-G:18.75-G,18.75)}rem`)}}),document.addEventListener("touchend",()=>{if(I){const y=(Y-R)/10;n(0,L=L?y>-(18.75/2):y>18.75/2)}I=!1})});const Q=y=>{c(y),n(0,L=!1)},ie=y=>y.key==="Enter"?P():{};function ee(y){Tn[y?"unshift":"push"](()=>{v=y,n(3,v)})}return t.$$.update=()=>{if(t.$$.dirty[0]&1){const y=document.querySelector("#sidebar");y&&za(y,L)}},[L,o,h,v,l,d,c,k,b,O,_,P,D,W,Q,ie,ee]}class Wa extends $e{constructor(e){super(),Ze(this,e,Oa,Ta,je,{},null,[-1,-1])}}new Wa({target:document.querySelector("#app")}); diff --git a/examples/api/dist/index.html b/examples/api/dist/index.html index a3d79e1136b..843e37e3bca 100644 --- a/examples/api/dist/index.html +++ b/examples/api/dist/index.html @@ -3,7 +3,7 @@ - Svelte + Vite App + API Example App diff --git a/examples/api/index.html b/examples/api/index.html index 3b39b0f66a9..df11ed2eaed 100644 --- a/examples/api/index.html +++ b/examples/api/index.html @@ -3,7 +3,7 @@ - Svelte + Vite App + API Example App diff --git a/examples/api/package.json b/examples/api/package.json index 654c53662dd..b1ab6873451 100644 --- a/examples/api/package.json +++ b/examples/api/package.json @@ -1,11 +1,12 @@ { - "name": "svelte-app", + "name": "api", + "private": true, "version": "1.0.0", "type": "module", "scripts": { - "dev": "vite --clearScreen false", + "dev": "vite", "build": "vite build", - "serve": "vite preview", + "preview": "vite preview", "tauri": "node ../../tooling/cli/node/tauri.js" }, "dependencies": { diff --git a/examples/api/src-tauri/Cargo.lock b/examples/api/src-tauri/Cargo.lock index 360bea2edc0..2312caa0da5 100644 --- a/examples/api/src-tauri/Cargo.lock +++ b/examples/api/src-tauri/Cargo.lock @@ -2091,6 +2091,7 @@ dependencies = [ "objc", "once_cell", "png", + "serde", "thiserror", "windows-sys 0.48.0", ] @@ -3884,6 +3885,7 @@ dependencies = [ "objc", "once_cell", "png", + "serde", "thiserror", "windows-sys 0.48.0", ] diff --git a/examples/api/src-tauri/src/lib.rs b/examples/api/src-tauri/src/lib.rs index 58e12a29192..1eb026c406e 100644 --- a/examples/api/src-tauri/src/lib.rs +++ b/examples/api/src-tauri/src/lib.rs @@ -2,11 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -#![cfg_attr( - all(not(debug_assertions), target_os = "windows"), - windows_subsystem = "windows" -)] - mod cmd; #[cfg(desktop)] mod tray; diff --git a/examples/api/src-tauri/tauri.conf.json b/examples/api/src-tauri/tauri.conf.json index 20bf653403b..95efe9a3f98 100644 --- a/examples/api/src-tauri/tauri.conf.json +++ b/examples/api/src-tauri/tauri.conf.json @@ -2,7 +2,7 @@ "$schema": "../../../core/tauri-config-schema/schema.json", "build": { "distDir": "../dist", - "devPath": "http://localhost:5173", + "devPath": "http://localhost:1420", "beforeDevCommand": "yarn dev", "beforeBuildCommand": "yarn build", "withGlobalTauri": true @@ -26,11 +26,7 @@ "name": "theme", "takesValue": true, "description": "App theme", - "possibleValues": [ - "light", - "dark", - "system" - ] + "possibleValues": ["light", "dark", "system"] }, { "short": "v", @@ -93,9 +89,7 @@ "csp": { "default-src": "'self' customprotocol: asset:", "connect-src": "ipc: http://ipc.localhost", - "font-src": [ - "https://fonts.gstatic.com" - ], + "font-src": ["https://fonts.gstatic.com"], "img-src": "'self' asset: http://asset.localhost blob: data:", "style-src": "'unsafe-inline' 'self' https://fonts.googleapis.com" }, @@ -103,15 +97,10 @@ "assetProtocol": { "enable": true, "scope": { - "allow": [ - "$APPDATA/db/**", - "$RESOURCE/**" - ], - "deny": [ - "$APPDATA/db/*.stronghold" - ] + "allow": ["$APPDATA/db/**", "$RESOURCE/**"], + "deny": ["$APPDATA/db/*.stronghold"] } } } } -} \ No newline at end of file +} diff --git a/examples/api/src/App.svelte b/examples/api/src/App.svelte index e5e14bc6411..654f5e1b839 100644 --- a/examples/api/src/App.svelte +++ b/examples/api/src/App.svelte @@ -8,7 +8,8 @@ import Window from './views/Window.svelte' import WebRTC from './views/WebRTC.svelte' import App from './views/App.svelte' - + import Menu from './views/Menu.svelte' + import Tray from './views/Tray.svelte' document.addEventListener('keydown', (event) => { if (event.ctrlKey && event.key === 'b') { @@ -40,6 +41,16 @@ component: Window, icon: 'i-codicon-window' }, + { + label: 'Menu', + component: Menu, + icon: 'i-ph-list' + }, + { + label: 'Tray', + component: Tray, + icon: 'i-ph-tray' + }, { label: 'WebRTC', component: WebRTC, @@ -299,16 +310,21 @@ class="select-none h-15rem grid grid-rows-[2px_2rem_1fr] gap-1 overflow-hidden" >

Console

e.key === "Enter"? clear() : {} } on:click={clear} >
diff --git a/examples/api/src/components/MenuBuilder.svelte b/examples/api/src/components/MenuBuilder.svelte new file mode 100644 index 00000000000..a79524bb8b4 --- /dev/null +++ b/examples/api/src/components/MenuBuilder.svelte @@ -0,0 +1,51 @@ + + +
+ + +
+ {#each items as item} +
+
+

{itemToString(item)}

+
+ {/each} +
+
diff --git a/examples/api/src/components/MenuItemBuilder.svelte b/examples/api/src/components/MenuItemBuilder.svelte new file mode 100644 index 00000000000..a2feea43584 --- /dev/null +++ b/examples/api/src/components/MenuItemBuilder.svelte @@ -0,0 +1,158 @@ + + +
+
+ {#each itemKinds as itemKind} +
+ + +
+ {/each} +
+ +
+ +
+ {#if kind == 'Normal' || kind == 'Icon' || kind == 'Check'} + + {/if} + {#if kind == 'Icon'} + + {:else if kind == 'Check'} +
+ + +
+ {:else if kind == 'Predefined'} +
+ {#each predefinedOptions as predefinedOption} +
+ + +
+ {/each} +
+ {/if} +
+ +
+ +
+ +
+
diff --git a/examples/api/src/views/Menu.svelte b/examples/api/src/views/Menu.svelte new file mode 100644 index 00000000000..96be93ac639 --- /dev/null +++ b/examples/api/src/views/Menu.svelte @@ -0,0 +1,47 @@ + + +
+ + + +
diff --git a/examples/api/src/views/Tray.svelte b/examples/api/src/views/Tray.svelte new file mode 100644 index 00000000000..586b0ef7e0d --- /dev/null +++ b/examples/api/src/views/Tray.svelte @@ -0,0 +1,79 @@ + + +
+
+ + + + + +
+ +
+ + + +
+ +
+ +
+ +
+ +
+
diff --git a/examples/api/src/views/WebRTC.svelte b/examples/api/src/views/WebRTC.svelte index e0f9862a5ec..f646b2dc69e 100644 --- a/examples/api/src/views/WebRTC.svelte +++ b/examples/api/src/views/WebRTC.svelte @@ -42,7 +42,7 @@ }) onDestroy(() => { - window.stream.getTracks().forEach(function (track) { + window.stream?.getTracks().forEach(function (track) { track.stop() }) }) diff --git a/examples/api/src/views/Window.svelte b/examples/api/src/views/Window.svelte index e0795414971..7e31d7f4f8d 100644 --- a/examples/api/src/views/Window.svelte +++ b/examples/api/src/views/Window.svelte @@ -10,7 +10,6 @@ ProgressBarStatus, Window } from '@tauri-apps/api/window' - import { invoke } from '@tauri-apps/api/primitives' const appWindow = getCurrent() @@ -309,9 +308,9 @@ {#if windowMap[selectedWindow]}
- +
- +
diff --git a/examples/api/src/vite-env.d.ts b/examples/api/src/vite-env.d.ts new file mode 100644 index 00000000000..c4b24aee8df --- /dev/null +++ b/examples/api/src/vite-env.d.ts @@ -0,0 +1,6 @@ +// Copyright 2019-2023 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +/// +/// diff --git a/examples/api/vite.config.js b/examples/api/vite.config.js index 903762f57b3..89551341419 100644 --- a/examples/api/vite.config.js +++ b/examples/api/vite.config.js @@ -21,15 +21,20 @@ export default defineConfig({ } } }, + + // Vite optons tailored for Tauri development and only applied in `tauri dev` or `tauri build` + // prevent vite from obscuring rust errors + clearScreen: false, + // tauri expects a fixed port, fail if that port is not available server: { host: mobile ? '0.0.0.0' : false, - port: 5173, + port: 1420, strictPort: true, hmr: mobile ? { protocol: 'ws', host: internalIpV4Sync(), - port: 5183 + port: 1421 } : undefined, fs: { diff --git a/examples/api/yarn.lock b/examples/api/yarn.lock index 14636dd0a62..3b6efee2b9b 100644 --- a/examples/api/yarn.lock +++ b/examples/api/yarn.lock @@ -11,18 +11,23 @@ "@jridgewell/trace-mapping" "^0.3.9" "@antfu/install-pkg@^0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@antfu/install-pkg/-/install-pkg-0.1.0.tgz#8d8c61820cbc32e5c37d82d515485ad3ee9bd052" - integrity sha512-VaIJd3d1o7irZfK1U0nvBsHMyjkuyMP3HKYVV53z8DKyulkHKmjhhtccXO51WSPeeSHIeoJEoNOKavYpS7jkZw== + version "0.1.1" + resolved "https://registry.yarnpkg.com/@antfu/install-pkg/-/install-pkg-0.1.1.tgz#157bb04f0de8100b9e4c01734db1a6c77e98bbb5" + integrity sha512-LyB/8+bSfa0DFGC06zpCEfs89/XoWZwws5ygEa5D+Xsm3OfI+aXQ86VgVG7Acyef+rSZ5HE7J8rrxzrQeM3PjQ== dependencies: execa "^5.1.1" find-up "^5.0.0" -"@antfu/utils@^0.5.0", "@antfu/utils@^0.5.1": +"@antfu/utils@^0.5.0": version "0.5.2" resolved "https://registry.yarnpkg.com/@antfu/utils/-/utils-0.5.2.tgz#8c2d931ff927be0ebe740169874a3d4004ab414b" integrity sha512-CQkeV+oJxUazwjlHD0/3ZD08QWKuGQkhnrKo3e6ly5pd48VUpXbb77q0xMU4+vc2CkJnDS02Eq/M9ugyX20XZA== +"@antfu/utils@^0.7.5": + version "0.7.6" + resolved "https://registry.yarnpkg.com/@antfu/utils/-/utils-0.7.6.tgz#30a046419b9e1ecd276e53d41ab68fb6c558c04d" + integrity sha512-pvFiLP2BeOKA/ZOS6jxx4XhKzdVLHDhGlFEaZ2flWWYf2xOqVniqpk38I04DFRyz+L0ASggl7SkItTc+ZLju4w== + "@esbuild/android-arm64@0.18.20": version "0.18.20" resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622" @@ -139,20 +144,25 @@ integrity sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ== "@iconify-json/codicon@^1.1.10": - version "1.1.10" - resolved "https://registry.yarnpkg.com/@iconify-json/codicon/-/codicon-1.1.10.tgz#22fee909be51afebfbcc6cd57209064b5363f202" - integrity sha512-xx3nX5k4UeDQnpX9D1T6L1RCEwyLtqu3Lqk9plYK+SoBSQ/kR73bPy9WbYyDVOw2MDw50JCSpZZYlBC718k7Sg== + version "1.1.28" + resolved "https://registry.yarnpkg.com/@iconify-json/codicon/-/codicon-1.1.28.tgz#b753f619a902e382dad6575fa8075aff8fb1d9e3" + integrity sha512-a4rcQ/Rh65QJbifXeb5eAqiXZmgen6oX0jM/BV/64Hh69EREHYVnjndTSdQq+rywCxG6ipiMJBrfBnjX4+20Sg== dependencies: - "@iconify/types" "^1.1.0" + "@iconify/types" "*" "@iconify-json/ph@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@iconify-json/ph/-/ph-1.1.1.tgz#17b3dee91a47055bac93d65c32b9ee33c654d56f" - integrity sha512-sIHTY+c1F8x29BM49IqoccJ3T8mvVXPcrE4WOpJ3GsBaip2YqFJRYU60rw64UL6GEI13vWSD7NsZKq8ytTO87g== + version "1.1.6" + resolved "https://registry.yarnpkg.com/@iconify-json/ph/-/ph-1.1.6.tgz#bbb7a3589199d91d8298bc084c4e893c8821ad8e" + integrity sha512-dexzEndlXQX/sbQhnEpA94Pby6JCGV2tZToSGcPPQpbilDGyk5VMd0ymusYoocRAn6+qLpGRvMoz5XFKGqP+VA== dependencies: - "@iconify/types" "^1.0.12" + "@iconify/types" "*" -"@iconify/types@^1.0.12", "@iconify/types@^1.1.0": +"@iconify/types@*": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@iconify/types/-/types-2.0.0.tgz#ab0e9ea681d6c8a1214f30cd741fe3a20cc57f57" + integrity sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg== + +"@iconify/types@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@iconify/types/-/types-1.1.0.tgz#dc15fc988b1b3fd558dd140a24ede7e0aac11280" integrity sha512-Jh0llaK2LRXQoYsorIH8maClebsnzTcve+7U3rQUSnC11X4jtPnFuyatqFLvMxZ8MLG8dB4zfHsbPfuvxluONw== @@ -256,7 +266,7 @@ vitefu "^0.2.4" "@tauri-apps/api@../../tooling/api/dist": - version "2.0.0-alpha.8" + version "2.0.0-alpha.9" "@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.1": version "1.0.2" @@ -418,9 +428,9 @@ acorn@^8.10.0, acorn@^8.9.0: integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== anymatch@~3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" - integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== dependencies: normalize-path "^3.0.0" picomatch "^2.0.4" @@ -452,9 +462,9 @@ braces@^3.0.2, braces@~3.0.2: fill-range "^7.0.1" cac@^6.7.12: - version "6.7.12" - resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.12.tgz#6fb5ea2ff50bd01490dbda497f4ae75a99415193" - integrity sha512-rM7E2ygtMkJqD9c7WnFU6fruFcN3xe4FM5yUmgxhZzIKJk4uHl9U/fhwdajGFQbQuv43FAUo1Fe8gX/oIKDeSA== + version "6.7.14" + resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959" + integrity sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ== chokidar@^3.5.3: version "3.5.3" @@ -483,9 +493,9 @@ code-red@^1.0.3: periscopic "^3.1.0" colorette@^2.0.16: - version "2.0.19" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" - integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== + version "2.0.20" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== consola@^2.15.3: version "2.15.3" @@ -501,15 +511,7 @@ cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" -css-tree@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.1.0.tgz#170e27ccf94e7c5facb183765c25898be843d1d2" - integrity sha512-PcysZRzToBbrpoUrZ9qfblRIRf8zbEAkU0AIpQFtgkFK0vSbzOmBCvdSAx2Zg7Xx5wiYJKUKk0NMP7kxevie/A== - dependencies: - mdn-data "2.0.27" - source-map-js "^1.0.1" - -css-tree@^2.3.1: +css-tree@^2.1.0, css-tree@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20" integrity sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw== @@ -536,20 +538,20 @@ default-gateway@^6.0.3: dependencies: execa "^5.0.0" -defu@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/defu/-/defu-6.0.0.tgz#b397a6709a2f3202747a3d9daf9446e41ad0c5fc" - integrity sha512-t2MZGLf1V2rV4VBZbWIaXKdX/mUcYW0n2znQZoADBkGGxYL8EWqCuCZBmJPJ/Yy9fofJkyuuSuo5GSwo0XdEgw== +defu@^6.1.2: + version "6.1.2" + resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.2.tgz#1217cba167410a1765ba93893c6dbac9ed9d9e5c" + integrity sha512-+uO4+qr7msjNNWKYPHqN/3+Dx3NFkmIzayk2L1MyZQlvgZb/J1A0fo410dpKrN2SnqFjt8n4JL8fDJE0wIgjFQ== dequal@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== -destr@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/destr/-/destr-1.1.1.tgz#910457d10a2f2f247add4ca4fdb4a03adcc49079" - integrity sha512-QqkneF8LrYmwATMdnuD2MLI3GHQIcBnG6qFC2q9bSH430VTCDAVjcspPmUaKhPGtAtPAftIUFqY1obQYQuwmbg== +destr@^1.2.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/destr/-/destr-1.2.2.tgz#7ba9befcafb645a50e76b260449c63927b51e22f" + integrity sha512-lrbCJwD9saUQrqUfXvl6qoM+QN3W7tLV5pAOs+OqOmopCCz/JkE05MHedJR1xfk4IAnZuJXPVuN5+7jNA2ZCiA== duplexer@^0.1.2: version "0.1.2" @@ -612,9 +614,9 @@ execa@^5.0.0, execa@^5.1.1: strip-final-newline "^2.0.0" fast-glob@^3.2.11: - version "3.2.11" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" - integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== + version "3.3.1" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" + integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -623,9 +625,9 @@ fast-glob@^3.2.11: micromatch "^4.0.4" fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== dependencies: reusify "^1.0.4" @@ -645,9 +647,9 @@ find-up@^5.0.0: path-exists "^4.0.0" fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== get-stream@^6.0.0: version "6.0.1" @@ -689,9 +691,9 @@ ip-regex@^4.0.0: integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== ipaddr.js@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" - integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== + version "2.1.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.1.0.tgz#2119bc447ff8c257753b196fc5f1ce08a4cdf39f" + integrity sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ== is-binary-path@~2.1.0: version "2.1.0" @@ -741,10 +743,15 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -jiti@^1.13.0: - version "1.14.0" - resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.14.0.tgz#5350fff532a4d891ca4bcd700c47c1f40e6ee326" - integrity sha512-4IwstlaKQc9vCTC+qUXLM1hajy2ImiL9KnLvVYiaHOtS/v3wRjhLlGl121AmgDgx/O43uKmxownJghS5XMya2A== +jiti@^1.19.1: + version "1.19.3" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.19.3.tgz#ef554f76465b3c2b222dc077834a71f0d4a37569" + integrity sha512-5eEbBDQT/jF1xg6l36P+mWGGoH9Spuy0PCdSr2dtWRDGC6ph/w9ZCL4lmESW8f8F7MwT3XKescfP0wnZWAKL9w== + +jsonc-parser@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" + integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== kleur@^4.1.5: version "4.1.5" @@ -752,14 +759,14 @@ kleur@^4.1.5: integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== kolorist@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/kolorist/-/kolorist-1.5.1.tgz#c3d66dc4fabde4f6b7faa6efda84c00491f9e52b" - integrity sha512-lxpCM3HTvquGxKGzHeknB/sUjuVoUElLlfYnXZT73K8geR9jQbroGlSCFBax9/0mpGoD3kzcMLnOlGQPJJNyqQ== + version "1.8.0" + resolved "https://registry.yarnpkg.com/kolorist/-/kolorist-1.8.0.tgz#edddbbbc7894bc13302cdf740af6374d4a04743c" + integrity sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ== local-pkg@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/local-pkg/-/local-pkg-0.4.1.tgz#e7b0d7aa0b9c498a1110a5ac5b00ba66ef38cfff" - integrity sha512-lL87ytIGP2FU5PWwNDo0w3WhIo2gopIAxPg9RxDYF7m4rr5ahuZxP22xnJHIvaLTe4Z9P6uKKY2UHiwyB4pcrw== + version "0.4.3" + resolved "https://registry.yarnpkg.com/local-pkg/-/local-pkg-0.4.3.tgz#0ff361ab3ae7f1c19113d9bb97b98b905dbc4963" + integrity sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g== locate-character@^3.0.0: version "3.0.0" @@ -774,9 +781,9 @@ locate-path@^6.0.0: p-locate "^5.0.0" magic-string@^0.26.2: - version "0.26.2" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.26.2.tgz#5331700e4158cd6befda738bb6b0c7b93c0d4432" - integrity sha512-NzzlXpclt5zAbmo6h6jNc8zl2gNRGHvmsZW4IvZhTC4W7k4OlLP+S5YLussa/r3ixNT66KOQfNORlXHSOy/X4A== + version "0.26.7" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.26.7.tgz#caf7daf61b34e9982f8228c4527474dac8981d6f" + integrity sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow== dependencies: sourcemap-codec "^1.4.8" @@ -787,11 +794,6 @@ magic-string@^0.30.0, magic-string@^0.30.3: dependencies: "@jridgewell/sourcemap-codec" "^1.4.15" -mdn-data@2.0.27: - version "2.0.27" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.27.tgz#1710baa7b0db8176d3b3d565ccb7915fc69525ab" - integrity sha512-kwqO0I0jtWr25KcfLm9pia8vLZ8qoAKhWZuZMbneJq3jjBD3gl5nZs8l8Tu3ZBlBAHVQtDur9rdDGyvtfVraHQ== - mdn-data@2.0.30: version "2.0.30" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.30.tgz#ce4df6f80af6cfbe218ecd5c552ba13c4dfa08cc" @@ -820,6 +822,16 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +mlly@^1.2.0, mlly@^1.4.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.4.1.tgz#7ab9cbb040bf8bd8205a0c341ce9acc3ae0c3a74" + integrity sha512-SCDs78Q2o09jiZiE2WziwVBEqXQ02XkGdUy45cbJf+BpYRIjArXRJ1Wbowxkb+NaM9DWvS3UC9GiO/6eqvQ/pg== + dependencies: + acorn "^8.10.0" + pathe "^1.1.1" + pkg-types "^1.0.3" + ufo "^1.3.0" + mrmime@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-1.0.1.tgz#5f90c825fad4bdd41dc914eff5d1a8cfdaf24f27" @@ -835,10 +847,10 @@ nanoid@^3.3.6: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== -node-fetch-native@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-0.1.4.tgz#09b06754f9e298bac23848050da2352125634f89" - integrity sha512-10EKpOCQPXwZVFh3U1ptOMWBgKTbsN7Vvo6WVKt5pw4hp8zbv6ZVBZPlXw+5M6Tyi1oc1iD4/sNPd71KYA16tQ== +node-fetch-native@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-0.1.8.tgz#19e2eaf6d86ac14e711ebd2612f40517c3468f2a" + integrity sha512-ZNaury9r0NxaT2oL65GvdGDy+5PlSaHTovT6JV5tOW07k1TQmgC0olZETa4C9KZg0+6zBr99ctTYa3Utqj9P/Q== normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" @@ -853,14 +865,14 @@ npm-run-path@^4.0.1: path-key "^3.0.0" ohmyfetch@^0.4.18: - version "0.4.18" - resolved "https://registry.yarnpkg.com/ohmyfetch/-/ohmyfetch-0.4.18.tgz#2952e04bd52662d0618d3d2f344db0250c3eeac2" - integrity sha512-MslzNrQzBLtZHmiZBI8QMOcMpdNFlK61OJ34nFNFynZ4v+4BonfCQ7VIN4EGXvGGq5zhDzgdJoY3o9S1l2T7KQ== + version "0.4.21" + resolved "https://registry.yarnpkg.com/ohmyfetch/-/ohmyfetch-0.4.21.tgz#6850db751fc7bbf08153aa8b11ff1ef45fcfd963" + integrity sha512-VG7f/JRvqvBOYvL0tHyEIEG7XHWm7OqIfAs6/HqwWwDfjiJ1g0huIpe5sFEmyb+7hpFa1EGNH2aERWR72tlClw== dependencies: - destr "^1.1.1" - node-fetch-native "^0.1.3" - ufo "^0.8.4" - undici "^5.2.0" + destr "^1.2.0" + node-fetch-native "^0.1.8" + ufo "^0.8.6" + undici "^5.12.0" onetime@^5.1.2: version "5.1.2" @@ -913,9 +925,14 @@ path-key@^3.0.0, path-key@^3.1.0: integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== pathe@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/pathe/-/pathe-0.3.0.tgz#fd95bc16208263fa6dc1c78c07b3907a528de6eb" - integrity sha512-3vUjp552BJzCw9vqKsO5sttHkbYqqsZtH0x1PNtItgqx8BXEXzoY1SYRKcL6BTyVh4lGJGLj0tM42elUDMvcYA== + version "0.3.9" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-0.3.9.tgz#4baff768f37f03e3d9341502865fb93116f65191" + integrity sha512-6Y6s0vT112P3jD8dGfuS6r+lpa0qqNrLyHPOwvXMnyNTQaYiwgau2DP3aNDsR13xqtGj7rrPo+jFUATpU6/s+g== + +pathe@^1.1.0, pathe@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.1.tgz#1dd31d382b974ba69809adc9a7a347e65d84829a" + integrity sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q== perfect-debounce@^0.1.3: version "0.1.3" @@ -936,15 +953,19 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -picomatch@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" - integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== +pkg-types@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.0.3.tgz#988b42ab19254c01614d13f4f65a2cfc7880f868" + integrity sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A== + dependencies: + jsonc-parser "^3.2.0" + mlly "^1.2.0" + pathe "^1.1.0" postcss@^8.4.27: version "8.4.31" @@ -1004,20 +1025,15 @@ signal-exit@^3.0.3: integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== sirv@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/sirv/-/sirv-2.0.2.tgz#128b9a628d77568139cff85703ad5497c46a4760" - integrity sha512-4Qog6aE29nIjAOKe/wowFTxOdmbEZKb+3tsLljaBRzJwtqto0BChD2zzH0LhgCSXiI+V7X+Y45v14wBZQ1TK3w== + version "2.0.3" + resolved "https://registry.yarnpkg.com/sirv/-/sirv-2.0.3.tgz#ca5868b87205a74bef62a469ed0296abceccd446" + integrity sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA== dependencies: "@polka/url" "^1.0.0-next.20" mrmime "^1.0.0" totalist "^3.0.0" -source-map-js@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.1.tgz#a1741c131e3c77d048252adfa24e23b908670caf" - integrity sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA== - -source-map-js@^1.0.2: +source-map-js@^1.0.1, source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== @@ -1064,28 +1080,34 @@ to-regex-range@^5.0.1: is-number "^7.0.0" totalist@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/totalist/-/totalist-3.0.0.tgz#4ef9c58c5f095255cdc3ff2a0a55091c57a3a1bd" - integrity sha512-eM+pCBxXO/njtF7vdFsHuqb+ElbxqtI4r5EAvk6grfAFyJ6IvWlSkfZ5T9ozC6xWw3Fj1fGoSmrl0gUs46JVIw== + version "3.0.1" + resolved "https://registry.yarnpkg.com/totalist/-/totalist-3.0.1.tgz#ba3a3d600c915b1a97872348f79c127475f6acf8" + integrity sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ== + +ufo@^0.8.6: + version "0.8.6" + resolved "https://registry.yarnpkg.com/ufo/-/ufo-0.8.6.tgz#c0ec89bc0e0c9fa59a683680feb0f28b55ec323b" + integrity sha512-fk6CmUgwKCfX79EzcDQQpSCMxrHstvbLswFChHS0Vump+kFkw7nJBfTZoC1j0bOGoY9I7R3n2DGek5ajbcYnOw== -ufo@^0.8.4: - version "0.8.4" - resolved "https://registry.yarnpkg.com/ufo/-/ufo-0.8.4.tgz#23e9ed82398d2116dcb378e8fba5ced8eca2ee40" - integrity sha512-/+BmBDe8GvlB2nIflWasLLAInjYG0bC9HRnfEpNi4sw77J2AJNnEVnTDReVrehoh825+Q/evF3THXTAweyam2g== +ufo@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.3.0.tgz#c92f8ac209daff607c57bbd75029e190930a0019" + integrity sha512-bRn3CsoojyNStCZe0BG0Mt4Nr/4KF+rhFlnNXybgqt5pXHNFRlqinSoQaTrGyzE4X8aHplSb+TorH+COin9Yxw== unconfig@^0.3.4: - version "0.3.4" - resolved "https://registry.yarnpkg.com/unconfig/-/unconfig-0.3.4.tgz#f0c85584a088a434dde2215d8a3b272427d6056c" - integrity sha512-cf39F1brwQuLSuMLTYXOdWJH0O1CJee6a4QW1nYtO7SoBUfVvQCvEel6ssTNXtPfi17kop1ADmVtmC49NlFkIQ== - dependencies: - "@antfu/utils" "^0.5.1" - defu "^6.0.0" - jiti "^1.13.0" - -undici@^5.2.0: - version "5.26.3" - resolved "https://registry.yarnpkg.com/undici/-/undici-5.26.3.tgz#ab3527b3d5bb25b12f898dfd22165d472dd71b79" - integrity sha512-H7n2zmKEWgOllKkIUkLvFmsJQj062lSm3uA4EYApG8gLuiOM0/go9bIoC3HVaSnfg4xunowDE2i9p8drkXuvDw== + version "0.3.10" + resolved "https://registry.yarnpkg.com/unconfig/-/unconfig-0.3.10.tgz#2439cfc4303c8e12f7333d7cb7286917a3eb9b63" + integrity sha512-tj317lhIq2iZF/NXrJnU1t2UaGUKKz1eL1sK2t63Oq66V9BxqvZV12m55fp/fpQJ+DDmVlLgo7cnLVOZkhlO/A== + dependencies: + "@antfu/utils" "^0.7.5" + defu "^6.1.2" + jiti "^1.19.1" + mlly "^1.4.0" + +undici@^5.12.0: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.26.5.tgz#f6dc8c565e3cad8c4475b187f51a13e505092838" + integrity sha512-cSb4bPFd5qgR7qr2jYAi0hlX9n5YKK2ONKkLFkxl+v/9BvC0sOpZjBHDBSXc5lWAf5ty9oZdRXytBIHzgUcerw== dependencies: "@fastify/busboy" "^2.0.0" diff --git a/tooling/api/.eslintrc b/tooling/api/.eslintrc index a996283f902..86d13228137 100644 --- a/tooling/api/.eslintrc +++ b/tooling/api/.eslintrc @@ -9,7 +9,6 @@ "parser": "@typescript-eslint/parser", "extends": [ - "standard-with-typescript", "plugin:@typescript-eslint/recommended-requiring-type-checking", // TODO: make this work with typescript // "plugin:node/recommended" diff --git a/tooling/api/package.json b/tooling/api/package.json index 032ec47144b..20a86ec2037 100644 --- a/tooling/api/package.json +++ b/tooling/api/package.json @@ -20,10 +20,10 @@ "homepage": "https://github.com/tauri-apps/tauri#readme", "type": "module", "scripts": { - "build": "yarn rollup --config rollup.config.ts --configPlugin typescript", + "build": "rollup -c --configPlugin typescript", "npm-pack": "yarn build && cd ./dist && npm pack", "npm-publish": "yarn build && cd ./dist && yarn publish --access public --loglevel silly --tag next", - "check": "tsc", + "ts:check": "tsc -noEmit", "lint": "eslint --ext ts \"./src/**/*.ts\"", "lint:fix": "eslint --fix --ext ts \"./src/**/*.ts\"", "format": "prettier --write . --config ../../.prettierrc --ignore-path .gitignore --ignore-path ../../.prettierignore", @@ -37,7 +37,6 @@ "@typescript-eslint/parser": "6.10.0", "eslint": "8.53.0", "eslint-config-prettier": "9.0.0", - "eslint-config-standard-with-typescript": "39.1.1", "eslint-plugin-import": "2.29.0", "eslint-plugin-n": "16.3.0", "eslint-plugin-node": "11.1.0", diff --git a/tooling/api/rollup.config.ts b/tooling/api/rollup.config.ts index 37f327dbf93..29fbbcb3a17 100644 --- a/tooling/api/rollup.config.ts +++ b/tooling/api/rollup.config.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -import { defineConfig, Plugin } from 'rollup' +import { defineConfig, Plugin, RollupLog } from 'rollup' import typescript from '@rollup/plugin-typescript' import terser from '@rollup/plugin-terser' import fg from 'fast-glob' @@ -31,6 +31,7 @@ export default defineConfig([ format: 'esm', dir: './dist', preserveModules: true, + preserveModulesRoot: 'src', entryFileNames: (chunkInfo) => { if (chunkInfo.name.includes('node_modules')) { return chunkInfo.name.replace('node_modules', 'external') + '.js' @@ -43,6 +44,7 @@ export default defineConfig([ format: 'cjs', dir: './dist', preserveModules: true, + preserveModulesRoot: 'src', entryFileNames: (chunkInfo) => { if (chunkInfo.name.includes('node_modules')) { return chunkInfo.name.replace('node_modules', 'external') + '.cjs' @@ -55,11 +57,12 @@ export default defineConfig([ plugins: [ typescript({ declaration: true, - declarationDir: './dist', + declarationDir: './dist/types', rootDir: 'src' }), makeFlatPackageInDist() - ] + ], + onwarn }, { @@ -67,13 +70,19 @@ export default defineConfig([ output: { format: 'iife', name: '__TAURI_IIFE__', - file: '../../core/tauri/scripts/bundle.global.js', - footer: 'window.__TAURI__ = __TAURI_IIFE__' + footer: 'window.__TAURI__ = __TAURI_IIFE__', + file: '../../core/tauri/scripts/bundle.global.js' }, - plugins: [typescript(), terser()] + plugins: [typescript(), terser()], + onwarn } ]) +function onwarn(warning: RollupLog) { + // deny warnings by default + throw Object.assign(new Error(), warning) +} + function makeFlatPackageInDist(): Plugin { return { name: 'makeFlatPackageInDist', @@ -88,13 +97,17 @@ function makeFlatPackageInDist(): Plugin { exports: Object.assign( {}, ...mods.map((mod) => { - let temp: Record = {} + let temp: Record< + string, + { types: string; import: string; require: string } + > = {} let key = `./${mod}` if (mod === 'index') { key = '.' } temp[key] = { + types: `./types/${mod}.d.ts`, import: `./${mod}.js`, require: `./${mod}.cjs` } diff --git a/tooling/api/src/event.ts b/tooling/api/src/event.ts index e03f4a69355..04e833639f2 100644 --- a/tooling/api/src/event.ts +++ b/tooling/api/src/event.ts @@ -55,8 +55,7 @@ enum TauriEvent { WINDOW_THEME_CHANGED = 'tauri://theme-changed', WINDOW_FILE_DROP = 'tauri://file-drop', WINDOW_FILE_DROP_HOVER = 'tauri://file-drop-hover', - WINDOW_FILE_DROP_CANCELLED = 'tauri://file-drop-cancelled', - MENU = 'tauri://menu' + WINDOW_FILE_DROP_CANCELLED = 'tauri://file-drop-cancelled' } /** diff --git a/tooling/api/src/index.ts b/tooling/api/src/index.ts index cc943e3f1c3..4717ed8452f 100644 --- a/tooling/api/src/index.ts +++ b/tooling/api/src/index.ts @@ -19,5 +19,7 @@ import * as primitives from './primitives' import * as window from './window' import * as path from './path' import * as dpi from './dpi' +import * as tray from './tray' +import * as menu from './menu' -export { app, dpi, event, path, primitives, window } +export { app, dpi, event, path, primitives, window, tray, menu } diff --git a/tooling/api/src/internal/index.ts b/tooling/api/src/internal/index.ts new file mode 100644 index 00000000000..55875d5d101 --- /dev/null +++ b/tooling/api/src/internal/index.ts @@ -0,0 +1,34 @@ +// Copyright 2019-2023 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +import { invoke } from '../primitives' + +/** + * A rust-backed resource. + * + * The resource lives in the main process and does not exist + * in the Javascript world, and thus will not be cleaned up automatiacally + * except on application exit. If you want to clean it up early, call {@linkcode Resource.close} + */ +export class Resource { + readonly #rid: number + + get rid(): number { + return this.#rid + } + + constructor(rid: number) { + this.#rid = rid + } + + /** + * Destroys and cleans up this resource from memory. + * **You should not call any method on this object anymore and should drop any reference to it.** + */ + async close(): Promise { + return invoke('plugin:resources|close', { + rid: this.rid + }) + } +} diff --git a/tooling/api/src/menu.ts b/tooling/api/src/menu.ts new file mode 100644 index 00000000000..a32c1b16ba5 --- /dev/null +++ b/tooling/api/src/menu.ts @@ -0,0 +1,17 @@ +// Copyright 2019-2023 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +export * from './menu/submenu' +export * from './menu/menuItem' +export * from './menu/menu' +export * from './menu/checkMenuItem' +export * from './menu/iconMenuItem' +export * from './menu/predefinedMenuItem' + +/** + * Menu types and utilities. + * + * This package is also accessible with `window.__TAURI__.menu` when [`build.withGlobalTauri`](https://tauri.app/v1/api/config/#buildconfig.withglobaltauri) in `tauri.conf.json` is set to `true`. + * @module + */ diff --git a/tooling/api/src/menu/base.ts b/tooling/api/src/menu/base.ts new file mode 100644 index 00000000000..7ca111f7172 --- /dev/null +++ b/tooling/api/src/menu/base.ts @@ -0,0 +1,114 @@ +// Copyright 2019-2023 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +import { Resource } from '../internal' +import { Channel, invoke } from '../primitives' +import { CheckMenuItemOptions } from './checkMenuItem' +import { IconMenuItemOptions } from './iconMenuItem' +import { MenuItemOptions } from './menuItem' +import { PredefinedMenuItemOptions } from './predefinedMenuItem' +import { SubmenuOptions } from './submenu' + +export type ItemKind = + | 'MenuItem' + | 'Predefined' + | 'Check' + | 'Icon' + | 'Submenu' + | 'Menu' + +function injectChannel( + i: + | MenuItemOptions + | SubmenuOptions + | IconMenuItemOptions + | PredefinedMenuItemOptions + | CheckMenuItemOptions +): + | MenuItemOptions + | SubmenuOptions + | IconMenuItemOptions + | PredefinedMenuItemOptions + | (CheckMenuItemOptions & { handler?: Channel }) { + if ('items' in i) { + i.items = i.items?.map((item) => + 'rid' in item ? item : injectChannel(item) + ) + } else if ('action' in i && i.action) { + const handler = new Channel() + handler.onmessage = i.action + delete i.action + return { ...i, handler } + } + return i +} + +export async function newMenu( + kind: ItemKind, + opts?: unknown +): Promise<[number, string]> { + const handler = new Channel() + let items: null | Array< + | [number, string] + | MenuItemOptions + | SubmenuOptions + | IconMenuItemOptions + | PredefinedMenuItemOptions + | CheckMenuItemOptions + > = null + if (opts && typeof opts === 'object') { + if ('action' in opts && opts.action) { + handler.onmessage = opts.action as () => void + delete opts.action + } + + if ('items' in opts && opts.items) { + items = ( + opts.items as Array< + | { rid: number; kind: string } + | MenuItemOptions + | SubmenuOptions + | IconMenuItemOptions + | PredefinedMenuItemOptions + | CheckMenuItemOptions + > + ).map((i) => { + if ('rid' in i) { + return [i.rid, i.kind] + } + return injectChannel(i) + }) + } + } + + return invoke('plugin:menu|new', { + kind, + options: opts ? { ...opts, items } : undefined, + handler + }) +} + +export class MenuItemBase extends Resource { + /** @ignore */ + readonly #id: string + /** @ignore */ + readonly #kind: ItemKind + + /** The id of this item. */ + get id(): string { + return this.#id + } + + /** @ignore */ + get kind(): string { + return this.#kind + } + + /** @ignore */ + protected constructor(rid: number, id: string, kind: ItemKind) { + super(rid) + this.#id = id + this.#kind = kind + } +} diff --git a/tooling/api/src/menu/checkMenuItem.ts b/tooling/api/src/menu/checkMenuItem.ts new file mode 100644 index 00000000000..692159cbdc1 --- /dev/null +++ b/tooling/api/src/menu/checkMenuItem.ts @@ -0,0 +1,82 @@ +// Copyright 2019-2023 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +import { MenuItemBase, newMenu } from './base' +import { invoke } from '../primitives' +import { type MenuItemOptions } from '../menu' + +/** Options for creating a new check menu item. */ +export interface CheckMenuItemOptions extends MenuItemOptions { + /** Whether the new check menu item is enabled or not. */ + checked?: boolean +} + +/** + * A check menu item inside a {@linkcode Menu} or {@linkcode Submenu} + * and usually contains a text and a check mark or a similar toggle + * that corresponds to a checked and unchecked states. + */ +export class CheckMenuItem extends MenuItemBase { + /** @ignore */ + protected constructor(rid: number, id: string) { + super(rid, id, 'Check') + } + + /** Create a new check menu item. */ + static async new(opts: CheckMenuItemOptions): Promise { + return newMenu('Check', opts).then( + ([rid, id]) => new CheckMenuItem(rid, id) + ) + } + + /** Returns the text of this check menu item. */ + async text(): Promise { + return invoke('plugin:menu|text', { rid: this.rid, kind: this.kind }) + } + + /** Sets the text for this check menu item. */ + async setText(text: string): Promise { + return invoke('plugin:menu|set_text', { + rid: this.rid, + kind: this.kind, + text + }) + } + + /** Returns whether this check menu item is enabled or not. */ + async isEnabled(): Promise { + return invoke('plugin:menu|is_enabled', { rid: this.rid, kind: this.kind }) + } + + /** Sets whether this check menu item is enabled or not. */ + async setEnabled(enabled: boolean): Promise { + return invoke('plugin:menu|set_enabled', { + rid: this.rid, + kind: this.kind, + enabled + }) + } + + /** Sets the accelerator for this check menu item. */ + async setAccelerator(accelerator: string | null): Promise { + return invoke('plugin:menu|set_accelerator', { + rid: this.rid, + kind: this.kind, + accelerator + }) + } + + /** Returns whether this check menu item is checked or not. */ + async isChecked(): Promise { + return invoke('plugin:menu|is_checked', { rid: this.rid }) + } + + /** Sets whether this check menu item is checked or not. */ + async setChecked(checked: boolean): Promise { + return invoke('plugin:menu|set_checked', { + rid: this.rid, + checked + }) + } +} diff --git a/tooling/api/src/menu/iconMenuItem.ts b/tooling/api/src/menu/iconMenuItem.ts new file mode 100644 index 00000000000..03faeb5af6a --- /dev/null +++ b/tooling/api/src/menu/iconMenuItem.ts @@ -0,0 +1,195 @@ +// Copyright 2019-2023 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +import { MenuItemBase, newMenu } from './base' +import { type MenuItemOptions } from '../menu' +import { invoke } from '../primitives' + +/** + * A native Icon to be used for the menu item + * + * #### Platform-specific: + * + * - **Windows / Linux**: Unsupported. + */ +export enum NativeIcon { + /** An add item template image. */ + Add = 'Add', + /** Advanced preferences toolbar icon for the preferences window. */ + Advanced = 'Advanced', + /** A Bluetooth template image. */ + Bluetooth = 'Bluetooth', + /** Bookmarks image suitable for a template. */ + Bookmarks = 'Bookmarks', + /** A caution image. */ + Caution = 'Caution', + /** A color panel toolbar icon. */ + ColorPanel = 'ColorPanel', + /** A column view mode template image. */ + ColumnView = 'ColumnView', + /** A computer icon. */ + Computer = 'Computer', + /** An enter full-screen mode template image. */ + EnterFullScreen = 'EnterFullScreen', + /** Permissions for all users. */ + Everyone = 'Everyone', + /** An exit full-screen mode template image. */ + ExitFullScreen = 'ExitFullScreen', + /** A cover flow view mode template image. */ + FlowView = 'FlowView', + /** A folder image. */ + Folder = 'Folder', + /** A burnable folder icon. */ + FolderBurnable = 'FolderBurnable', + /** A smart folder icon. */ + FolderSmart = 'FolderSmart', + /** A link template image. */ + FollowLinkFreestanding = 'FollowLinkFreestanding', + /** A font panel toolbar icon. */ + FontPanel = 'FontPanel', + /** A `go back` template image. */ + GoLeft = 'GoLeft', + /** A `go forward` template image. */ + GoRight = 'GoRight', + /** Home image suitable for a template. */ + Home = 'Home', + /** An iChat Theater template image. */ + IChatTheater = 'IChatTheater', + /** An icon view mode template image. */ + IconView = 'IconView', + /** An information toolbar icon. */ + Info = 'Info', + /** A template image used to denote invalid data. */ + InvalidDataFreestanding = 'InvalidDataFreestanding', + /** A generic left-facing triangle template image. */ + LeftFacingTriangle = 'LeftFacingTriangle', + /** A list view mode template image. */ + ListView = 'ListView', + /** A locked padlock template image. */ + LockLocked = 'LockLocked', + /** An unlocked padlock template image. */ + LockUnlocked = 'LockUnlocked', + /** A horizontal dash, for use in menus. */ + MenuMixedState = 'MenuMixedState', + /** A check mark template image, for use in menus. */ + MenuOnState = 'MenuOnState', + /** A MobileMe icon. */ + MobileMe = 'MobileMe', + /** A drag image for multiple items. */ + MultipleDocuments = 'MultipleDocuments', + /** A network icon. */ + Network = 'Network', + /** A path button template image. */ + Path = 'Path', + /** General preferences toolbar icon for the preferences window. */ + PreferencesGeneral = 'PreferencesGeneral', + /** A Quick Look template image. */ + QuickLook = 'QuickLook', + /** A refresh template image. */ + RefreshFreestanding = 'RefreshFreestanding', + /** A refresh template image. */ + Refresh = 'Refresh', + /** A remove item template image. */ + Remove = 'Remove', + /** A reveal contents template image. */ + RevealFreestanding = 'RevealFreestanding', + /** A generic right-facing triangle template image. */ + RightFacingTriangle = 'RightFacingTriangle', + /** A share view template image. */ + Share = 'Share', + /** A slideshow template image. */ + Slideshow = 'Slideshow', + /** A badge for a `smart` item. */ + SmartBadge = 'SmartBadge', + /** Small green indicator, similar to iChat’s available image. */ + StatusAvailable = 'StatusAvailable', + /** Small clear indicator. */ + StatusNone = 'StatusNone', + /** Small yellow indicator, similar to iChat’s idle image. */ + StatusPartiallyAvailable = 'StatusPartiallyAvailable', + /** Small red indicator, similar to iChat’s unavailable image. */ + StatusUnavailable = 'StatusUnavailable', + /** A stop progress template image. */ + StopProgressFreestanding = 'StopProgressFreestanding', + /** A stop progress button template image. */ + StopProgress = 'StopProgress', + /** An image of the empty trash can. */ + TrashEmpty = 'TrashEmpty', + /** An image of the full trash can. */ + TrashFull = 'TrashFull', + /** Permissions for a single user. */ + User = 'User', + /** User account toolbar icon for the preferences window. */ + UserAccounts = 'UserAccounts', + /** Permissions for a group of users. */ + UserGroup = 'UserGroup', + /** Permissions for guests. */ + UserGuest = 'UserGuest' +} + +/** Options for creating a new icon menu item. */ +export interface IconMenuItemOptions extends MenuItemOptions { + /** + * Icon to be used for the new icon menu item. + */ + icon?: NativeIcon | string | Uint8Array +} + +/** + * An icon menu item inside a {@linkcode Menu} or {@linkcode Submenu} + * and usually contains an icon and a text. + */ +export class IconMenuItem extends MenuItemBase { + /** @ignore */ + protected constructor(rid: number, id: string) { + super(rid, id, 'Icon') + } + + /** Create a new icon menu item. */ + static async new(opts: IconMenuItemOptions): Promise { + return newMenu('Icon', opts).then(([rid, id]) => new IconMenuItem(rid, id)) + } + + /** Returns the text of this icon menu item. */ + async text(): Promise { + return invoke('plugin:menu|text', { rid: this.rid, kind: this.kind }) + } + + /** Sets the text for this icon menu item. */ + async setText(text: string): Promise { + return invoke('plugin:menu|set_text', { + rid: this.rid, + kind: this.kind, + text + }) + } + + /** Returns whether this icon menu item is enabled or not. */ + async isEnabled(): Promise { + return invoke('plugin:menu|is_enabled', { rid: this.rid, kind: this.kind }) + } + + /** Sets whether this icon menu item is enabled or not. */ + async setEnabled(enabled: boolean): Promise { + return invoke('plugin:menu|set_enabled', { + rid: this.rid, + kind: this.kind, + enabled + }) + } + + /** Sets the accelerator for this icon menu item. */ + async setAccelerator(accelerator: string | null): Promise { + return invoke('plugin:menu|set_accelerator', { + rid: this.rid, + kind: this.kind, + accelerator + }) + } + + /** Sets an icon for this icon menu item */ + async setIcon(icon: NativeIcon | string | Uint8Array | null): Promise { + return invoke('plugin:menu|set_icon', { rid: this.rid, icon }) + } +} diff --git a/tooling/api/src/menu/menu.ts b/tooling/api/src/menu/menu.ts new file mode 100644 index 00000000000..593b58eedfc --- /dev/null +++ b/tooling/api/src/menu/menu.ts @@ -0,0 +1,287 @@ +// Copyright 2019-2023 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +import { + MenuItemOptions, + SubmenuOptions, + IconMenuItemOptions, + PredefinedMenuItemOptions, + CheckMenuItemOptions +} from '../menu' +import { MenuItem } from './menuItem' +import { CheckMenuItem } from './checkMenuItem' +import { IconMenuItem } from './iconMenuItem' +import { PredefinedMenuItem } from './predefinedMenuItem' +import { Submenu } from './submenu' +import { type LogicalPosition, PhysicalPosition } from '../dpi' +import { type Window } from '../window' +import { invoke } from '../primitives' +import { type ItemKind, MenuItemBase, newMenu } from './base' + +function itemFromKind([rid, id, kind]: [number, string, ItemKind]): + | Submenu + | MenuItem + | PredefinedMenuItem + | CheckMenuItem + | IconMenuItem { + /* eslint-disable @typescript-eslint/no-unsafe-return */ + switch (kind) { + case 'Submenu': + // @ts-expect-error constructor is protected for external usage only + return new Submenu(rid, id) + case 'Predefined': + // @ts-expect-error constructor is protected for external usage only + return new PredefinedMenuItem(rid, id) + case 'Check': + // @ts-expect-error constructor is protected for external usage only + return new CheckMenuItem(rid, id) + case 'Icon': + // @ts-expect-error constructor is protected for external usage only + return new IconMenuItem(rid, id) + case 'MenuItem': + default: + // @ts-expect-error constructor is protected for external usage only + return new MenuItem(rid, id) + } + /* eslint-enable @typescript-eslint/no-unsafe-return */ +} + +/** Options for creating a new menu. */ +export interface MenuOptions { + /** Specify an id to use for the new menu. */ + id?: string + /** List of items to add to the new menu. */ + items?: Array< + | Submenu + | MenuItem + | PredefinedMenuItem + | CheckMenuItem + | IconMenuItem + | MenuItemOptions + | SubmenuOptions + | IconMenuItemOptions + | PredefinedMenuItemOptions + | CheckMenuItemOptions + > +} + +/** A type that is either a menu bar on the window + * on Windows and Linux or as a global menu in the menubar on macOS. + */ +export class Menu extends MenuItemBase { + /** @ignore */ + protected constructor(rid: number, id: string) { + super(rid, id, 'Menu') + } + + /** Create a new menu. */ + static async new(opts?: MenuOptions): Promise { + return newMenu('Menu', opts).then(([rid, id]) => new Menu(rid, id)) + } + + /** Create a default menu. */ + static async default(): Promise { + return invoke<[number, string]>('plugin:menu|default').then( + ([rid, id]) => new Menu(rid, id) + ) + } + + /** + * Add a menu item to the end of this menu. + * + * ## Platform-spcific: + * + * - **macOS:** Only {@linkcode Submenu}s can be added to a {@linkcode Menu}. + */ + async append< + T extends + | Submenu + | MenuItem + | PredefinedMenuItem + | CheckMenuItem + | IconMenuItem + | MenuItemOptions + | SubmenuOptions + | IconMenuItemOptions + | PredefinedMenuItemOptions + | CheckMenuItemOptions + >(items: T | T[]): Promise { + return invoke('plugin:menu|append', { + rid: this.rid, + kind: this.kind, + items: (Array.isArray(items) ? items : [items]).map((i) => + 'rid' in i ? [i.rid, i.kind] : i + ) + }) + } + + /** + * Add a menu item to the beginning of this menu. + * + * ## Platform-spcific: + * + * - **macOS:** Only {@linkcode Submenu}s can be added to a {@linkcode Menu}. + */ + async prepend< + T extends + | Submenu + | MenuItem + | PredefinedMenuItem + | CheckMenuItem + | IconMenuItem + | MenuItemOptions + | SubmenuOptions + | IconMenuItemOptions + | PredefinedMenuItemOptions + | CheckMenuItemOptions + >(items: T | T[]): Promise { + return invoke('plugin:menu|prepend', { + rid: this.rid, + kind: this.kind, + items: (Array.isArray(items) ? items : [items]).map((i) => + 'rid' in i ? [i.rid, i.kind] : i + ) + }) + } + + /** + * Add a menu item to the specified position in this menu. + * + * ## Platform-spcific: + * + * - **macOS:** Only {@linkcode Submenu}s can be added to a {@linkcode Menu}. + */ + async insert< + T extends + | Submenu + | MenuItem + | PredefinedMenuItem + | CheckMenuItem + | IconMenuItem + | MenuItemOptions + | SubmenuOptions + | IconMenuItemOptions + | PredefinedMenuItemOptions + | CheckMenuItemOptions + >(items: T | T[], position: number): Promise { + return invoke('plugin:menu|insert', { + rid: this.rid, + kind: this.kind, + items: (Array.isArray(items) ? items : [items]).map((i) => + 'rid' in i ? [i.rid, i.kind] : i + ), + position + }) + } + + /** Remove a menu item from this menu. */ + async remove( + item: Submenu | MenuItem | PredefinedMenuItem | CheckMenuItem | IconMenuItem + ): Promise { + return invoke('plugin:menu|remove', { + rid: this.rid, + kind: this.kind, + item: [item.rid, item.kind] + }) + } + + /** Remove a menu item from this menu at the specified position. */ + async removeAt( + position: number + ): Promise< + | Submenu + | MenuItem + | PredefinedMenuItem + | CheckMenuItem + | IconMenuItem + | null + > { + return invoke<[number, string, ItemKind]>('plugin:menu|remove_at', { + rid: this.rid, + kind: this.kind, + position + }).then(itemFromKind) + } + + /** Returns a list of menu items that has been added to this menu. */ + async items(): Promise< + Array< + Submenu | MenuItem | PredefinedMenuItem | CheckMenuItem | IconMenuItem + > + > { + return invoke>('plugin:menu|items', { + rid: this.rid, + kind: this.kind + }).then((i) => i.map(itemFromKind)) + } + + /** Retrieves the menu item matching the given identifier. */ + async get( + id: string + ): Promise< + | Submenu + | MenuItem + | PredefinedMenuItem + | CheckMenuItem + | IconMenuItem + | null + > { + return invoke<[number, string, ItemKind] | null>('plugin:menu|get', { + rid: this.rid, + kind: this.kind, + id + }).then((r) => (r ? itemFromKind(r) : null)) + } + + /** + * Popup this menu as a context menu on the specified window. + * + * If the position, is provided, it is relative to the window's top-left corner. + */ + async popup( + at?: PhysicalPosition | LogicalPosition, + window?: Window + ): Promise { + let atValue = null + if (at) { + atValue = { + type: at instanceof PhysicalPosition ? 'Physical' : 'Logical', + data: at + } + } + return invoke('plugin:menu|popup', { + rid: this.rid, + kind: this.kind, + window: window?.label ?? null, + at: atValue + }) + } + + /** + * Sets the app-wide menu and returns the previous one. + * + * If a window was not created with an explicit menu or had one set explicitly, + * this menu will be assigned to it. + */ + async setAsAppMenu(): Promise { + return invoke<[number, string] | null>('plugin:menu|set_as_app_menu', { + rid: this.rid + }).then((r) => (r ? new Menu(r[0], r[1]) : null)) + } + + /** + * Sets the window menu and returns the previous one. + * + * #### Platform-specific: + * + * - **macOS:** Unsupported. The menu on macOS is app-wide and not specific to one + * window, if you need to set it, use {@linkcode Menu.setAsAppMenu} instead. + */ + async setAsWindowMenu(window?: Window): Promise { + return invoke<[number, string] | null>('plugin:menu|set_as_window_menu', { + rid: this.rid, + window: window?.label ?? null + }).then((r) => (r ? new Menu(r[0], r[1]) : null)) + } +} diff --git a/tooling/api/src/menu/menuItem.ts b/tooling/api/src/menu/menuItem.ts new file mode 100644 index 00000000000..97990b05da0 --- /dev/null +++ b/tooling/api/src/menu/menuItem.ts @@ -0,0 +1,70 @@ +// Copyright 2019-2023 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +import { MenuItemBase, newMenu } from './base' +import { invoke } from '../primitives' + +/** Options for creating a new menu item. */ +export interface MenuItemOptions { + /** Specify an id to use for the new menu item. */ + id?: string + /** The text of the new menu item. */ + text: string + /** Whether the new menu item is enabled or not. */ + enabled?: boolean + /** Specify an accelerator for the new menu item. */ + accelerator?: string + /** Specify a handler to be called when this menu item is activated. */ + action?: (id: string) => void +} + +/** A menu item inside a {@linkcode Menu} or {@linkcode Submenu} and contains only text. */ +export class MenuItem extends MenuItemBase { + /** @ignore */ + protected constructor(rid: number, id: string) { + super(rid, id, 'MenuItem') + } + + /** Create a new menu item. */ + static async new(opts: MenuItemOptions): Promise { + return newMenu('MenuItem', opts).then(([rid, id]) => new MenuItem(rid, id)) + } + + /** Returns the text of this menu item. */ + async text(): Promise { + return invoke('plugin:menu|text', { rid: this.rid, kind: this.kind }) + } + + /** Sets the text for this menu item. */ + async setText(text: string): Promise { + return invoke('plugin:menu|set_text', { + rid: this.rid, + kind: this.kind, + text + }) + } + + /** Returns whether this menu item is enabled or not. */ + async isEnabled(): Promise { + return invoke('plugin:menu|is_enabled', { rid: this.rid, kind: this.kind }) + } + + /** Sets whether this menu item is enabled or not. */ + async setEnabled(enabled: boolean): Promise { + return invoke('plugin:menu|set_enabled', { + rid: this.rid, + kind: this.kind, + enabled + }) + } + + /** Sets the accelerator for this menu item. */ + async setAccelerator(accelerator: string | null): Promise { + return invoke('plugin:menu|set_accelerator', { + rid: this.rid, + kind: this.kind, + accelerator + }) + } +} diff --git a/tooling/api/src/menu/predefinedMenuItem.ts b/tooling/api/src/menu/predefinedMenuItem.ts new file mode 100644 index 00000000000..3f45c728487 --- /dev/null +++ b/tooling/api/src/menu/predefinedMenuItem.ts @@ -0,0 +1,138 @@ +// Copyright 2019-2023 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +import { MenuItemBase, newMenu } from './base' +import { invoke } from '../primitives' + +/** A metadata for the about predefined menu item. */ +export interface AboutMetadata { + /** Sets the application name. */ + name?: string + /** The application version. */ + version?: string + /** + * The short version, e.g. "1.0". + * + * #### Platform-specific + * + * - **Windows / Linux:** Appended to the end of `version` in parentheses. + */ + shortVersion?: string + /** + * The authors of the application. + * + * #### Platform-specific + * + * - **macOS:** Unsupported. + */ + authors?: string[] + /** + * Application comments. + * + * #### Platform-specific + * + * - **macOS:** Unsupported. + */ + comments?: string + /** The copyright of the application. */ + copyright?: string + /** + * The license of the application. + * + * #### Platform-specific + * + * - **macOS:** Unsupported. + */ + license?: string + /** + * The application website. + * + * #### Platform-specific + * + * - **macOS:** Unsupported. + */ + website?: string + /** + * The website label. + * + * #### Platform-specific + * + * - **macOS:** Unsupported. + */ + websiteLabel?: string + /** + * The credits. + * + * #### Platform-specific + * + * - **Windows / Linux:** Unsupported. + */ + credits?: string + /** + * The application icon. + * + * #### Platform-specific + * + * - **Windows:** Unsupported. + */ + icon?: string | Uint8Array +} + +/** Options for creating a new predefined menu item. */ +export interface PredefinedMenuItemOptions { + /** The text of the new predefined menu item. */ + text?: string + /** The predefined item type */ + item: + | 'Separator' + | 'Copy' + | 'Cut' + | 'Paste' + | 'SelectAll' + | 'Undo' + | 'Redo' + | 'Minimize' + | 'Maximize' + | 'Fullscreen' + | 'Hide' + | 'HideOthers' + | 'ShowAll' + | 'CloseWindow' + | 'Quit' + | 'Services' + | { + About: AboutMetadata | null + } +} + +/** A predefined (native) menu item which has a predfined behavior by the OS or by tauri. */ +export class PredefinedMenuItem extends MenuItemBase { + /** @ignore */ + protected constructor(rid: number, id: string) { + super(rid, id, 'Predefined') + } + + /** Create a new predefined menu item. */ + static async new( + opts?: PredefinedMenuItemOptions + ): Promise { + return newMenu('Predefined', opts).then( + ([rid, id]) => new PredefinedMenuItem(rid, id) + ) + } + + /** Returns the text of this predefined menu item. */ + async text(): Promise { + return invoke('plugin:menu|text', { rid: this.rid, kind: this.kind }) + } + + /** Sets the text for this predefined menu item. */ + async setText(text: string): Promise { + return invoke('plugin:menu|set_text', { + rid: this.rid, + kind: this.kind, + text + }) + } +} diff --git a/tooling/api/src/menu/submenu.ts b/tooling/api/src/menu/submenu.ts new file mode 100644 index 00000000000..96456ad1812 --- /dev/null +++ b/tooling/api/src/menu/submenu.ts @@ -0,0 +1,294 @@ +// Copyright 2019-2023 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +import { + IconMenuItemOptions, + PredefinedMenuItemOptions, + CheckMenuItemOptions +} from '../menu' +import { MenuItem, type MenuItemOptions } from './menuItem' +import { CheckMenuItem } from './checkMenuItem' +import { IconMenuItem } from './iconMenuItem' +import { PredefinedMenuItem } from './predefinedMenuItem' +import { invoke } from '../primitives' +import { type LogicalPosition, PhysicalPosition, type Window } from '../window' +import { type ItemKind, MenuItemBase, newMenu } from './base' +import { type MenuOptions } from './menu' + +function itemFromKind([rid, id, kind]: [number, string, ItemKind]): + | Submenu + | MenuItem + | PredefinedMenuItem + | CheckMenuItem + | IconMenuItem { + /* eslint-disable @typescript-eslint/no-unsafe-return */ + switch (kind) { + case 'Submenu': + // @ts-expect-error constructor is protected for external usage only, safe for us to use + return new Submenu(rid, id) + case 'Predefined': + // @ts-expect-error constructor is protected for external usage only, safe for us to use + return new PredefinedMenuItem(rid, id) + case 'Check': + // @ts-expect-error constructor is protected for external usage only, safe for us to use + return new CheckMenuItem(rid, id) + case 'Icon': + // @ts-expect-error constructor is protected for external usage only, safe for us to use + return new IconMenuItem(rid, id) + case 'MenuItem': + default: + // @ts-expect-error constructor is protected for external usage only, safe for us to use + return new MenuItem(rid, id) + } + /* eslint-enable @typescript-eslint/no-unsafe-return */ +} + +export type SubmenuOptions = Omit & + MenuOptions + +/** A type that is a submenu inside a {@linkcode Menu} or {@linkcode Submenu}. */ +export class Submenu extends MenuItemBase { + /** @ignore */ + protected constructor(rid: number, id: string) { + super(rid, id, 'Submenu') + } + + /** Create a new submenu. */ + static async new(opts: SubmenuOptions): Promise { + return newMenu('Submenu', opts).then(([rid, id]) => new Submenu(rid, id)) + } + + /** Returns the text of this submenu. */ + async text(): Promise { + return invoke('plugin:menu|text', { rid: this.rid, kind: this.kind }) + } + + /** Sets the text for this submenu. */ + async setText(text: string): Promise { + return invoke('plugin:menu|set_text', { + rid: this.rid, + kind: this.kind, + text + }) + } + + /** Returns whether this submenu is enabled or not. */ + async isEnabled(): Promise { + return invoke('plugin:menu|is_enabled', { rid: this.rid, kind: this.kind }) + } + + /** Sets whether this submenu is enabled or not. */ + async setEnabled(enabled: boolean): Promise { + return invoke('plugin:menu|set_enabled', { + rid: this.rid, + kind: this.kind, + enabled + }) + } + + /** + * Add a menu item to the end of this submenu. + * + * ## Platform-spcific: + * + * - **macOS:** Only {@linkcode Submenu}s can be added to a {@linkcode Menu}. + */ + async append< + T extends + | Submenu + | MenuItem + | PredefinedMenuItem + | CheckMenuItem + | IconMenuItem + | MenuItemOptions + | SubmenuOptions + | IconMenuItemOptions + | PredefinedMenuItemOptions + | CheckMenuItemOptions + >(items: T | T[]): Promise { + return invoke('plugin:menu|append', { + rid: this.rid, + kind: this.kind, + items: (Array.isArray(items) ? items : [items]).map((i) => + 'rid' in i ? [i.rid, i.kind] : i + ) + }) + } + + /** + * Add a menu item to the beginning of this submenu. + * + * ## Platform-spcific: + * + * - **macOS:** Only {@linkcode Submenu}s can be added to a {@linkcode Menu}. + */ + async prepend< + T extends + | Submenu + | MenuItem + | PredefinedMenuItem + | CheckMenuItem + | IconMenuItem + | MenuItemOptions + | SubmenuOptions + | IconMenuItemOptions + | PredefinedMenuItemOptions + | CheckMenuItemOptions + >(items: T | T[]): Promise { + return invoke('plugin:menu|prepend', { + rid: this.rid, + kind: this.kind, + items: (Array.isArray(items) ? items : [items]).map((i) => + 'rid' in i ? [i.rid, i.kind] : i + ) + }) + } + + /** + * Add a menu item to the specified position in this submenu. + * + * ## Platform-spcific: + * + * - **macOS:** Only {@linkcode Submenu}s can be added to a {@linkcode Menu}. + */ + async insert< + T extends + | Submenu + | MenuItem + | PredefinedMenuItem + | CheckMenuItem + | IconMenuItem + | MenuItemOptions + | SubmenuOptions + | IconMenuItemOptions + | PredefinedMenuItemOptions + | CheckMenuItemOptions + >(items: T | T[], position: number): Promise { + return invoke('plugin:menu|insert', { + rid: this.rid, + kind: this.kind, + items: (Array.isArray(items) ? items : [items]).map((i) => + 'rid' in i ? [i.rid, i.kind] : i + ), + position + }) + } + + /** Remove a menu item from this submenu. */ + async remove( + item: Submenu | MenuItem | PredefinedMenuItem | CheckMenuItem | IconMenuItem + ): Promise { + return invoke('plugin:menu|remove', { + rid: this.rid, + kind: this.kind, + item: [item.rid, item.kind] + }) + } + + /** Remove a menu item from this submenu at the specified position. */ + async removeAt( + position: number + ): Promise< + | Submenu + | MenuItem + | PredefinedMenuItem + | CheckMenuItem + | IconMenuItem + | null + > { + return invoke<[number, string, ItemKind]>('plugin:menu|remove_at', { + rid: this.rid, + kind: this.kind, + position + }).then(itemFromKind) + } + + /** Returns a list of menu items that has been added to this submenu. */ + async items(): Promise< + Array< + Submenu | MenuItem | PredefinedMenuItem | CheckMenuItem | IconMenuItem + > + > { + return invoke>('plugin:menu|items', { + rid: this.rid, + kind: this.kind + }).then((i) => i.map(itemFromKind)) + } + + /** Retrieves the menu item matching the given identifier. */ + async get( + id: string + ): Promise< + | Submenu + | MenuItem + | PredefinedMenuItem + | CheckMenuItem + | IconMenuItem + | null + > { + return invoke<[number, string, ItemKind] | null>('plugin:menu|get', { + rid: this.rid, + kind: this.kind, + id + }).then((r) => (r ? itemFromKind(r) : null)) + } + + /** + * Popup this submenu as a context menu on the specified window. + * + * If the position, is provided, it is relative to the window's top-left corner. + */ + async popup( + at?: PhysicalPosition | LogicalPosition, + window?: Window + ): Promise { + let atValue = null + if (at) { + atValue = { + type: at instanceof PhysicalPosition ? 'Physical' : 'Logical', + data: at + } + } + return invoke('plugin:menu|popup', { + rid: this.rid, + kind: this.kind, + window: window?.label ?? null, + at: atValue + }) + } + + /** + * Set this submenu as the Window menu for the application on macOS. + * + * This will cause macOS to automatically add window-switching items and + * certain other items to the menu. + * + * #### Platform-specific: + * + * - **Windows / Linux**: Unsupported. + */ + async setAsWindowsMenuForNSApp(): Promise { + return invoke('plugin:menu|set_as_windows_menu_for_nsapp', { + rid: this.rid + }) + } + + /** + * Set this submenu as the Help menu for the application on macOS. + * + * This will cause macOS to automatically add a search box to the menu. + * + * If no menu is set as the Help menu, macOS will automatically use any menu + * which has a title matching the localized word "Help". + * + * #### Platform-specific: + * + * - **Windows / Linux**: Unsupported. + */ + async setAsHelpMenuForNSApp(): Promise { + return invoke('plugin:menu|set_as_help_menu_for_nsapp', { + rid: this.rid + }) + } +} diff --git a/tooling/api/src/path.ts b/tooling/api/src/path.ts index acc7c3b9be5..1a737ca1160 100644 --- a/tooling/api/src/path.ts +++ b/tooling/api/src/path.ts @@ -533,7 +533,7 @@ async function appLogDir(): Promise { * * @since 2.0.0 */ -async function tempDir(path: string): Promise { +async function tempDir(): Promise { return invoke('plugin:path|resolve_directory', { directory: BaseDirectory.Temp }) diff --git a/tooling/api/src/tray.ts b/tooling/api/src/tray.ts new file mode 100644 index 00000000000..15724078a5b --- /dev/null +++ b/tooling/api/src/tray.ts @@ -0,0 +1,235 @@ +// Copyright 2019-2023 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +import type { Menu, Submenu } from './menu' +import { Resource } from './internal' +import { Channel, invoke } from './primitives' + +/** + * Describes a tray event emitted when a tray icon is clicked + * + * #### Platform-specific: + * + * - **Linux**: Unsupported. The event is not emmited even though the icon is shown, + * the icon will still show a context menu on right click. + */ +export interface TrayIconEvent { + /** Id of the tray icon which triggered this event. */ + id: string + /** Physical X Position of the click the triggered this event. */ + x: number + /** Physical Y Position of the click the triggered this event. */ + y: number + /** Position and size of the tray icon. */ + iconRect: { + /** The x-coordinate of the upper-left corner of the rectangle. */ + left: number + /** The y-coordinate of the upper-left corner of the rectangle. */ + top: number + /** The x-coordinate of the lower-right corner of the rectangle. */ + right: number + /** The y-coordinate of the lower-right corner of the rectangle. */ + bottom: number + } + /** The click type that triggered this event. */ + clickType: 'Left' | 'Right' | 'Double' +} + +/** + * Tray icon types and utilities. + * + * This package is also accessible with `window.__TAURI__.tray` when [`build.withGlobalTauri`](https://tauri.app/v1/api/config/#buildconfig.withglobaltauri) in `tauri.conf.json` is set to `true`. + * @module + */ + +/** {@link TrayIcon.new|`TrayIcon`} creation options */ +export interface TrayIconOptions { + /** The tray icon id. If undefined, a random one will be assigend */ + id?: string + /** The tray icon menu */ + menu?: Menu | Submenu + /** + * The tray icon which could be icon bytes or path to the icon file. + * + * Note that you need the `icon-ico` or `icon-png` Cargo features to use this API. + * To enable it, change your Cargo.toml file: + * ```toml + * [dependencies] + * tauri = { version = "...", features = ["...", "icon-png"] } + * ``` + */ + icon?: string | Uint8Array | number[] + /** The tray icon tooltip */ + tooltip?: string + /** + * The tray title + * + * #### Platform-specific + * + * - **Linux:** The title will not be shown unless there is an icon + * as well. The title is useful for numerical and other frequently + * updated information. In general, it shouldn't be shown unless a + * user requests it as it can take up a significant amount of space + * on the user's panel. This may not be shown in all visualizations. + * - **Windows:** Unsupported. + */ + title?: string + /** + * The tray icon temp dir path. **Linux only**. + * + * On Linux, we need to write the icon to the disk and usually it will + * be `$XDG_RUNTIME_DIR/tray-icon` or `$TEMP/tray-icon`. + */ + tempDirPath?: string + /** + * Use the icon as a [template](https://developer.apple.com/documentation/appkit/nsimage/1520017-template?language=objc). **macOS only**. + */ + iconAsTemplate?: boolean + /** Whether to show the tray menu on left click or not, default is `true`. **macOS only**. */ + menuOnLeftClick?: boolean + /** A handler for an event on the tray icon. */ + action?: (event: TrayIconEvent) => void +} + +/** + * Tray icon class and associated methods. This type constructor is private, + * instead, you should use the static method {@linkcode TrayIcon.new}. + * + * #### Warning + * + * Unlike Rust, javascript does not have any way to run cleanup code + * when an object is being removed by garbage collection, but this tray icon + * will be cleaned up when the tauri app exists, however if you want to cleanup + * this object early, you need to call {@linkcode TrayIcon.close}. + * + * @example + * ```ts + * import { TrayIcon } from '@tauri-apps/api/tray'; + * const tray = await TrayIcon.new({ tooltip: 'awesome tray tooltip' }); + * tray.set_tooltip('new tooltip'); + * ``` + */ +export class TrayIcon extends Resource { + /** The id associated with this tray icon. */ + public id: string + + private constructor(rid: number, id: string) { + super(rid) + this.id = id + } + + /** + * Creates a new {@linkcode TrayIcon} + * + * #### Platform-specific: + * + * - **Linux:** Sometimes the icon won't be visible unless a menu is set. + * Setting an empty {@linkcode Menu} is enough. + */ + static async new(options?: TrayIconOptions): Promise { + if (options?.menu) { + // @ts-expect-error we only need the rid and kind + options.menu = [options.menu.rid, options.menu.kind] + } + if (options?.icon) { + options.icon = + typeof options.icon === 'string' + ? options.icon + : Array.from(options.icon) + } + + const handler = new Channel() + if (options?.action) { + handler.onmessage = options.action + delete options.action + } + + return invoke<[number, string]>('plugin:tray|new', { + options: options ?? {}, + handler + }).then(([rid, id]) => new TrayIcon(rid, id)) + } + + /** Sets a new tray icon. If `null` is provided, it will remove the icon. */ + async setIcon(icon: string | Uint8Array | null): Promise { + let trayIcon = null + if (icon) { + trayIcon = typeof icon === 'string' ? icon : Array.from(icon) + } + return invoke('plugin:tray|set_icon', { rid: this.rid, icon: trayIcon }) + } + + /** + * Sets a new tray menu. + * + * #### Platform-specific: + * + * - **Linux**: once a menu is set it cannot be removed so `null` has no effect + */ + async setMenu(menu: Menu | Submenu | null): Promise { + if (menu) { + // @ts-expect-error we only need the rid and kind + menu = [menu.rid, menu.kind] + } + return invoke('plugin:tray|set_menu', { rid: this.rid, menu }) + } + + /** + * Sets the tooltip for this tray icon. + * + * ## Platform-specific: + * + * - **Linux:** Unsupported + */ + async setTooltip(tooltip: string | null): Promise { + return invoke('plugin:tray|set_tooltip', { rid: this.rid, tooltip }) + } + + /** + * Sets the tooltip for this tray icon. + * + * ## Platform-specific: + * + * - **Linux:** The title will not be shown unless there is an icon + * as well. The title is useful for numerical and other frequently + * updated information. In general, it shouldn't be shown unless a + * user requests it as it can take up a significant amount of space + * on the user's panel. This may not be shown in all visualizations. + * - **Windows:** Unsupported + */ + async setTitle(title: string | null): Promise { + return invoke('plugin:tray|set_title', { rid: this.rid, title }) + } + + /** Show or hide this tray icon. */ + async setVisible(visible: boolean): Promise { + return invoke('plugin:tray|set_visible', { rid: this.rid, visible }) + } + + /** + * Sets the tray icon temp dir path. **Linux only**. + * + * On Linux, we need to write the icon to the disk and usually it will + * be `$XDG_RUNTIME_DIR/tray-icon` or `$TEMP/tray-icon`. + */ + async setTempDirPath(path: string | null): Promise { + return invoke('plugin:tray|set_temp_dir_path', { rid: this.rid, path }) + } + + /** Sets the current icon as a [template](https://developer.apple.com/documentation/appkit/nsimage/1520017-template?language=objc). **macOS only** */ + async setIconAsTemplate(asTemplate: boolean): Promise { + return invoke('plugin:tray|set_icon_as_template', { + rid: this.rid, + asTemplate + }) + } + + /** Disable or enable showing the tray menu on left click. **macOS only**. */ + async setMenuOnLeftClick(onLeft: boolean): Promise { + return invoke('plugin:tray|set_show_menu_on_left_click', { + rid: this.rid, + onLeft + }) + } +} diff --git a/tooling/api/src/window.ts b/tooling/api/src/window.ts index 8cc1c16e53f..7de099a9c5b 100644 --- a/tooling/api/src/window.ts +++ b/tooling/api/src/window.ts @@ -1686,27 +1686,6 @@ class Window { ) } - /** - * Listen to the window menu item click. The payload is the item id. - * - * @example - * ```typescript - * import { getCurrent } from "@tauri-apps/api/window"; - * const unlisten = await getCurrent().onMenuClicked(({ payload: menuId }) => { - * console.log('Menu clicked: ' + menuId); - * }); - * - * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted - * unlisten(); - * ``` - * - * @returns A promise resolving to a function to unlisten to the event. - * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted. - */ - async onMenuClicked(handler: EventCallback): Promise { - return this.listen(TauriEvent.MENU, handler) - } - /** * Listen to a file drop event. * The listener is triggered when the user hovers the selected files on the window, diff --git a/tooling/api/yarn.lock b/tooling/api/yarn.lock index 252b18d1a63..2b7edd7cd41 100644 --- a/tooling/api/yarn.lock +++ b/tooling/api/yarn.lock @@ -15,9 +15,9 @@ eslint-visitor-keys "^3.3.0" "@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.0", "@eslint-community/regexpp@^4.6.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.9.1.tgz#449dfa81a57a1d755b09aa58d826c1262e4283b4" - integrity sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA== + version "4.10.0" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" + integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== "@eslint/eslintrc@^2.1.3": version "2.1.3" @@ -91,9 +91,9 @@ integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== "@jridgewell/trace-mapping@^0.3.9": - version "0.3.19" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz#f8a3249862f91be48d3127c3cfe992f79b4b8811" - integrity sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw== + version "0.3.20" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" + integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== dependencies: "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" @@ -206,14 +206,14 @@ integrity sha512-dMvGV8p92GQ8jhNlGIKpyhVZPzJlT258pPrM5q2F8lKcc9Iv9BbfdnhX1OfinYWnb9ms5zLw6MlaMnqLfUkKnQ== "@types/estree@^1.0.0": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.2.tgz#ff02bc3dc8317cd668dfec247b750ba1f1d62453" - integrity sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA== + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== "@types/json-schema@^7.0.12": - version "7.0.14" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.14.tgz#74a97a5573980802f32c8e47b663530ab3b6b7d1" - integrity sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw== + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== "@types/json5@^0.0.29": version "0.0.29" @@ -228,9 +228,9 @@ undici-types "~5.26.4" "@types/semver@^7.5.0": - version "7.5.4" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.4.tgz#0a41252ad431c473158b22f9bfb9a63df7541cff" - integrity sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ== + version "7.5.5" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.5.tgz#deed5ab7019756c9c90ea86139106b0346223f35" + integrity sha512-+d+WYC1BxJ6yVOgUgzK8gWvp5qF8ssV5r4nsDcZWKRWcDQLQ619tvWAxJQYGgBrO1MnLJC7a5GtiYsAoQ47dJg== "@typescript-eslint/eslint-plugin@6.10.0": version "6.10.0" @@ -260,17 +260,6 @@ "@typescript-eslint/visitor-keys" "6.10.0" debug "^4.3.4" -"@typescript-eslint/parser@^6.4.0": - version "6.9.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.9.0.tgz#2b402cadeadd3f211c25820e5433413347b27391" - integrity sha512-GZmjMh4AJ/5gaH4XF2eXA8tMnHWP+Pm1mjQR2QN4Iz+j/zO04b9TOvJYOX2sCNIQHtRStKTxRY1FX7LhpJT4Gw== - dependencies: - "@typescript-eslint/scope-manager" "6.9.0" - "@typescript-eslint/types" "6.9.0" - "@typescript-eslint/typescript-estree" "6.9.0" - "@typescript-eslint/visitor-keys" "6.9.0" - debug "^4.3.4" - "@typescript-eslint/scope-manager@6.10.0": version "6.10.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.10.0.tgz#b0276118b13d16f72809e3cecc86a72c93708540" @@ -279,14 +268,6 @@ "@typescript-eslint/types" "6.10.0" "@typescript-eslint/visitor-keys" "6.10.0" -"@typescript-eslint/scope-manager@6.9.0": - version "6.9.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.9.0.tgz#2626e9a7fe0e004c3e25f3b986c75f584431134e" - integrity sha512-1R8A9Mc39n4pCCz9o79qRO31HGNDvC7UhPhv26TovDsWPBDx+Sg3rOZdCELIA3ZmNoWAuxaMOT7aWtGRSYkQxw== - dependencies: - "@typescript-eslint/types" "6.9.0" - "@typescript-eslint/visitor-keys" "6.9.0" - "@typescript-eslint/type-utils@6.10.0": version "6.10.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.10.0.tgz#1007faede067c78bdbcef2e8abb31437e163e2e1" @@ -302,11 +283,6 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.10.0.tgz#f4f0a84aeb2ac546f21a66c6e0da92420e921367" integrity sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg== -"@typescript-eslint/types@6.9.0": - version "6.9.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.9.0.tgz#86a0cbe7ac46c0761429f928467ff3d92f841098" - integrity sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw== - "@typescript-eslint/typescript-estree@6.10.0": version "6.10.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.10.0.tgz#667381eed6f723a1a8ad7590a31f312e31e07697" @@ -320,19 +296,6 @@ semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/typescript-estree@6.9.0": - version "6.9.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.0.tgz#d0601b245be873d8fe49f3737f93f8662c8693d4" - integrity sha512-NJM2BnJFZBEAbCfBP00zONKXvMqihZCrmwCaik0UhLr0vAgb6oguXxLX1k00oQyD+vZZ+CJn3kocvv2yxm4awQ== - dependencies: - "@typescript-eslint/types" "6.9.0" - "@typescript-eslint/visitor-keys" "6.9.0" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.5.4" - ts-api-utils "^1.0.1" - "@typescript-eslint/utils@6.10.0": version "6.10.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.10.0.tgz#4d76062d94413c30e402c9b0df8c14aef8d77336" @@ -354,14 +317,6 @@ "@typescript-eslint/types" "6.10.0" eslint-visitor-keys "^3.4.1" -"@typescript-eslint/visitor-keys@6.9.0": - version "6.9.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.0.tgz#cc69421c10c4ac997ed34f453027245988164e80" - integrity sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg== - dependencies: - "@typescript-eslint/types" "6.9.0" - eslint-visitor-keys "^3.4.1" - "@ungap/structured-clone@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" @@ -373,9 +328,9 @@ acorn-jsx@^5.3.2: integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn@^8.8.2, acorn@^8.9.0: - version "8.10.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" - integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== + version "8.11.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b" + integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== ajv@^6.12.4: version "6.12.6" @@ -509,13 +464,14 @@ builtins@^5.0.1: dependencies: semver "^7.0.0" -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" + integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" + function-bind "^1.1.2" + get-intrinsic "^1.2.1" + set-function-length "^1.1.1" callsites@^3.0.0: version "3.1.0" @@ -580,7 +536,7 @@ deep-is@^0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== -define-data-property@^1.0.1: +define-data-property@^1.0.1, define-data-property@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== @@ -620,25 +576,25 @@ doctrine@^3.0.0: esutils "^2.0.2" es-abstract@^1.22.1: - version "1.22.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.2.tgz#90f7282d91d0ad577f505e423e52d4c1d93c1b8a" - integrity sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA== + version "1.22.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.3.tgz#48e79f5573198de6dee3589195727f4f74bc4f32" + integrity sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA== dependencies: array-buffer-byte-length "^1.0.0" arraybuffer.prototype.slice "^1.0.2" available-typed-arrays "^1.0.5" - call-bind "^1.0.2" + call-bind "^1.0.5" es-set-tostringtag "^2.0.1" es-to-primitive "^1.2.1" function.prototype.name "^1.1.6" - get-intrinsic "^1.2.1" + get-intrinsic "^1.2.2" get-symbol-description "^1.0.0" globalthis "^1.0.3" gopd "^1.0.1" - has "^1.0.3" has-property-descriptors "^1.0.0" has-proto "^1.0.1" has-symbols "^1.0.3" + hasown "^2.0.0" internal-slot "^1.0.5" is-array-buffer "^3.0.2" is-callable "^1.2.7" @@ -648,7 +604,7 @@ es-abstract@^1.22.1: is-string "^1.0.7" is-typed-array "^1.1.12" is-weakref "^1.0.2" - object-inspect "^1.12.3" + object-inspect "^1.13.1" object-keys "^1.1.1" object.assign "^4.1.4" regexp.prototype.flags "^1.5.1" @@ -662,23 +618,23 @@ es-abstract@^1.22.1: typed-array-byte-offset "^1.0.0" typed-array-length "^1.0.4" unbox-primitive "^1.0.2" - which-typed-array "^1.1.11" + which-typed-array "^1.1.13" es-set-tostringtag@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" - integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== + version "2.0.2" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz#11f7cc9f63376930a5f20be4915834f4bc74f9c9" + integrity sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q== dependencies: - get-intrinsic "^1.1.3" - has "^1.0.3" + get-intrinsic "^1.2.2" has-tostringtag "^1.0.0" + hasown "^2.0.0" es-shim-unscopables@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" - integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== + version "1.0.2" + resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz#1f6942e71ecc7835ed1c8a83006d8771a63a3763" + integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== dependencies: - has "^1.0.3" + hasown "^2.0.0" es-to-primitive@^1.2.1: version "1.2.1" @@ -699,19 +655,6 @@ eslint-config-prettier@9.0.0: resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz#eb25485946dd0c66cd216a46232dc05451518d1f" integrity sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw== -eslint-config-standard-with-typescript@39.1.1: - version "39.1.1" - resolved "https://registry.yarnpkg.com/eslint-config-standard-with-typescript/-/eslint-config-standard-with-typescript-39.1.1.tgz#d682bd1fc8f1ee996940f85c9b0a833d7cfa5fee" - integrity sha512-t6B5Ep8E4I18uuoYeYxINyqcXb2UbC0SOOTxRtBSt2JUs+EzeXbfe2oaiPs71AIdnoWhXDO2fYOHz8df3kV84A== - dependencies: - "@typescript-eslint/parser" "^6.4.0" - eslint-config-standard "17.1.0" - -eslint-config-standard@17.1.0: - version "17.1.0" - resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz#40ffb8595d47a6b242e07cbfd49dc211ed128975" - integrity sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q== - eslint-import-resolver-node@^0.3.9: version "0.3.9" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" @@ -729,9 +672,9 @@ eslint-module-utils@^2.8.0: debug "^3.2.7" eslint-plugin-es-x@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-es-x/-/eslint-plugin-es-x-7.2.0.tgz#5779d742ad31f8fd780b9481331481e142b72311" - integrity sha512-9dvv5CcvNjSJPqnS5uZkqb3xmbeqRLnvXKK7iI5+oK/yTusyc46zbBZKENGsOfojm/mKfszyZb+wNqNPAPeGXA== + version "7.3.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-es-x/-/eslint-plugin-es-x-7.3.0.tgz#c699280ad35cd315720c3cccf0fe503092c08788" + integrity sha512-W9zIs+k00I/I13+Bdkl/zG1MEO07G97XjUSQuH117w620SJ6bHtLUmoMvkGA2oYnI/gNdr+G7BONLyYnFaLLEQ== dependencies: "@eslint-community/eslint-utils" "^4.1.2" "@eslint-community/regexpp" "^4.6.0" @@ -918,7 +861,7 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@3.3.2: +fast-glob@3.3.2, fast-glob@^3.2.9: version "3.3.2" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== @@ -929,17 +872,6 @@ fast-glob@3.3.2: merge2 "^1.3.0" micromatch "^4.0.4" -fast-glob@^3.2.9: - version "3.3.1" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" - integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -980,9 +912,9 @@ find-up@^5.0.0: path-exists "^4.0.0" flat-cache@^3.0.4: - version "3.1.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.1.1.tgz#a02a15fdec25a8f844ff7cc658f03dd99eb4609b" - integrity sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q== + version "3.2.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" + integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== dependencies: flatted "^3.2.9" keyv "^4.5.3" @@ -1010,7 +942,7 @@ fsevents@~2.3.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== -function-bind@^1.1.1, function-bind@^1.1.2: +function-bind@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== @@ -1030,15 +962,15 @@ functions-have-names@^1.2.3: resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" - integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" + integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== dependencies: - function-bind "^1.1.1" - has "^1.0.3" + function-bind "^1.1.2" has-proto "^1.0.1" has-symbols "^1.0.3" + hasown "^2.0.0" get-symbol-description@^1.0.0: version "1.0.0" @@ -1130,11 +1062,11 @@ has-flag@^4.0.0: integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340" + integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== dependencies: - get-intrinsic "^1.1.1" + get-intrinsic "^1.2.2" has-proto@^1.0.1: version "1.0.1" @@ -1153,11 +1085,6 @@ has-tostringtag@^1.0.0: dependencies: has-symbols "^1.0.2" -has@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.4.tgz#2eb2860e000011dae4f1406a86fe80e530fb2ec6" - integrity sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ== - hasown@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" @@ -1197,12 +1124,12 @@ inherits@2: integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== internal-slot@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" - integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== + version "1.0.6" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.6.tgz#37e756098c4911c5e912b8edbf71ed3aa116f930" + integrity sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg== dependencies: - get-intrinsic "^1.2.0" - has "^1.0.3" + get-intrinsic "^1.2.2" + hasown "^2.0.0" side-channel "^1.0.4" is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: @@ -1234,14 +1161,7 @@ is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== -is-core-module@^2.12.1, is-core-module@^2.13.0: - version "2.13.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" - integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== - dependencies: - has "^1.0.3" - -is-core-module@^2.13.1: +is-core-module@^2.12.1, is-core-module@^2.13.0, is-core-module@^2.13.1: version "2.13.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== @@ -1445,10 +1365,10 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -object-inspect@^1.12.3, object-inspect@^1.9.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.0.tgz#42695d3879e1cd5bda6df5062164d80c996e23e2" - integrity sha512-HQ4J+ic8hKrgIt3mqk6cVOVrW2ozL4KdvHlqpBv9vDYWx9ysAgENAdvy4FoGF+KFdhR7nQTNm5J0ctAeOwn+3g== +object-inspect@^1.13.1, object-inspect@^1.9.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" + integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== object-keys@^1.1.1: version "1.1.1" @@ -1574,9 +1494,9 @@ prettier@3.0.3: integrity sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg== punycode@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== queue-microtask@^1.2.2: version "1.2.3" @@ -1716,6 +1636,16 @@ serialize-javascript@^6.0.1: dependencies: randombytes "^2.1.0" +set-function-length@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed" + integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ== + dependencies: + define-data-property "^1.1.1" + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + set-function-name@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a" @@ -1826,9 +1756,9 @@ supports-preserve-symlinks-flag@^1.0.0: integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== terser@^5.17.4: - version "5.22.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.22.0.tgz#4f18103f84c5c9437aafb7a14918273310a8a49d" - integrity sha512-hHZVLgRA2z4NWcN6aS5rQDc+7Dcy58HOf2zbYwmFcQ+ua3h6eEFf5lIDKTzbWwlazPyOZsFQO8V80/IjVNExEw== + version "5.24.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.24.0.tgz#4ae50302977bca4831ccc7b4fef63a3c04228364" + integrity sha512-ZpGR4Hy3+wBEzVEnHvstMvqpD/nABNelQn/z2r0fjVWGQsN3bpOLzQlqDxmb4CDZnXq5lpjnQ+mHQLAOpfM5iw== dependencies: "@jridgewell/source-map" "^0.3.3" acorn "^8.8.2" @@ -1956,13 +1886,13 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" -which-typed-array@^1.1.11: - version "1.1.11" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.11.tgz#99d691f23c72aab6768680805a271b69761ed61a" - integrity sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew== +which-typed-array@^1.1.11, which-typed-array@^1.1.13: + version "1.1.13" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" + integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== dependencies: available-typed-arrays "^1.0.5" - call-bind "^1.0.2" + call-bind "^1.0.4" for-each "^0.3.3" gopd "^1.0.1" has-tostringtag "^1.0.0"