Merge remote-tracking branch 'origin/main' into react/type_widgets

; Conflicts:
;	apps/client/src/layouts/desktop_layout.tsx
;	apps/client/src/layouts/mobile_layout.tsx
;	apps/client/src/widgets/note_detail.ts
;	apps/client/src/widgets/react/hooks.tsx
This commit is contained in:
Elian Doran 2025-11-09 12:08:50 +02:00
commit 33a41d2f86
No known key found for this signature in database
80 changed files with 1233 additions and 521 deletions

View File

@ -77,7 +77,7 @@ jobs:
GPG_SIGNING_KEY: ${{ secrets.GPG_SIGN_KEY }} GPG_SIGNING_KEY: ${{ secrets.GPG_SIGN_KEY }}
- name: Publish release - name: Publish release
uses: softprops/action-gh-release@v2.4.1 uses: softprops/action-gh-release@v2.4.2
if: ${{ github.event_name != 'pull_request' }} if: ${{ github.event_name != 'pull_request' }}
with: with:
make_latest: false make_latest: false
@ -118,7 +118,7 @@ jobs:
arch: ${{ matrix.arch }} arch: ${{ matrix.arch }}
- name: Publish release - name: Publish release
uses: softprops/action-gh-release@v2.4.1 uses: softprops/action-gh-release@v2.4.2
if: ${{ github.event_name != 'pull_request' }} if: ${{ github.event_name != 'pull_request' }}
with: with:
make_latest: false make_latest: false

View File

@ -127,7 +127,7 @@ jobs:
path: upload path: upload
- name: Publish stable release - name: Publish stable release
uses: softprops/action-gh-release@v2.4.1 uses: softprops/action-gh-release@v2.4.2
with: with:
draft: false draft: false
body_path: docs/Release Notes/Release Notes/${{ github.ref_name }}.md body_path: docs/Release Notes/Release Notes/${{ github.ref_name }}.md

View File

@ -46,7 +46,7 @@
"esm": "3.2.25", "esm": "3.2.25",
"jsdoc": "4.0.5", "jsdoc": "4.0.5",
"lorem-ipsum": "2.0.8", "lorem-ipsum": "2.0.8",
"rcedit": "4.0.1", "rcedit": "5.0.0",
"rimraf": "6.1.0", "rimraf": "6.1.0",
"tslib": "2.8.1" "tslib": "2.8.1"
}, },

View File

@ -43,7 +43,7 @@
"draggabilly": "3.0.0", "draggabilly": "3.0.0",
"force-graph": "1.51.0", "force-graph": "1.51.0",
"globals": "16.5.0", "globals": "16.5.0",
"i18next": "25.6.0", "i18next": "25.6.1",
"i18next-http-backend": "3.0.2", "i18next-http-backend": "3.0.2",
"jquery": "3.7.1", "jquery": "3.7.1",
"jquery.fancytree": "2.38.5", "jquery.fancytree": "2.38.5",
@ -53,7 +53,7 @@
"leaflet": "1.9.4", "leaflet": "1.9.4",
"leaflet-gpx": "2.2.0", "leaflet-gpx": "2.2.0",
"mark.js": "8.11.1", "mark.js": "8.11.1",
"marked": "16.4.1", "marked": "16.4.2",
"mermaid": "11.12.1", "mermaid": "11.12.1",
"mind-elixir": "5.3.5", "mind-elixir": "5.3.5",
"normalize.css": "8.0.1", "normalize.css": "8.0.1",

View File

@ -495,6 +495,10 @@ type EventMappings = {
noteIds: string[]; noteIds: string[];
}; };
refreshData: { ntxId: string | null | undefined }; refreshData: { ntxId: string | null | undefined };
contentSafeMarginChanged: {
top: number;
noteContext: NoteContext;
}
}; };
export type EventListener<T extends EventNames> = { export type EventListener<T extends EventNames> = {

View File

@ -171,7 +171,8 @@ export default class RootCommandExecutor extends Component {
} }
toggleTrayCommand() { toggleTrayCommand() {
if (!utils.isElectron()) return; if (!utils.isElectron() || options.is("disableTray")) return;
const { BrowserWindow } = utils.dynamicRequire("@electron/remote"); const { BrowserWindow } = utils.dynamicRequire("@electron/remote");
const windows = BrowserWindow.getAllWindows() as Electron.BaseWindow[]; const windows = BrowserWindow.getAllWindows() as Electron.BaseWindow[];
const isVisible = windows.every((w) => w.isVisible()); const isVisible = windows.every((w) => w.isVisible());

View File

@ -1,46 +1,48 @@
import FlexContainer from "../widgets/containers/flex_container.js";
import TabRowWidget from "../widgets/tab_row.js";
import LeftPaneContainer from "../widgets/containers/left_pane_container.js";
import NoteTreeWidget from "../widgets/note_tree.js";
import NoteTitleWidget from "../widgets/note_title.jsx";
import PromotedAttributesWidget from "../widgets/promoted_attributes.js";
import NoteIconWidget from "../widgets/note_icon.jsx";
import ScrollingContainer from "../widgets/containers/scrolling_container.js";
import RootContainer from "../widgets/containers/root_container.js";
import WatchedFileUpdateStatusWidget from "../widgets/watched_file_update_status.js";
import SpacerWidget from "../widgets/spacer.js";
import QuickSearchWidget from "../widgets/quick_search.js";
import SplitNoteContainer from "../widgets/containers/split_note_container.js";
import CreatePaneButton from "../widgets/buttons/create_pane_button.js";
import ClosePaneButton from "../widgets/buttons/close_pane_button.js";
import RightPaneContainer from "../widgets/containers/right_pane_container.js";
import NoteWrapperWidget from "../widgets/note_wrapper.js";
import FindWidget from "../widgets/find.js";
import TocWidget from "../widgets/toc.js";
import HighlightsListWidget from "../widgets/highlights_list.js";
import PasswordNoteSetDialog from "../widgets/dialogs/password_not_set.js";
import LauncherContainer from "../widgets/containers/launcher_container.js";
import MovePaneButton from "../widgets/buttons/move_pane_button.js";
import UploadAttachmentsDialog from "../widgets/dialogs/upload_attachments.js";
import ScrollPadding from "../widgets/scroll_padding.js";
import options from "../services/options.js";
import utils from "../services/utils.js";
import type { AppContext } from "../components/app_context.js";
import type { WidgetsByParent } from "../services/bundle.js";
import { applyModals } from "./layout_commons.js"; import { applyModals } from "./layout_commons.js";
import Ribbon from "../widgets/ribbon/Ribbon.jsx";
import FloatingButtons from "../widgets/FloatingButtons.jsx";
import { DESKTOP_FLOATING_BUTTONS } from "../widgets/FloatingButtonsDefinitions.jsx"; import { DESKTOP_FLOATING_BUTTONS } from "../widgets/FloatingButtonsDefinitions.jsx";
import SearchResult from "../widgets/search_result.jsx"; import ApiLog from "../widgets/api_log.jsx";
import ClosePaneButton from "../widgets/buttons/close_pane_button.js";
import CloseZenModeButton from "../widgets/close_zen_button.jsx";
import ContentHeader from "../widgets/containers/content-header.js";
import CreatePaneButton from "../widgets/buttons/create_pane_button.js";
import FindWidget from "../widgets/find.js";
import FlexContainer from "../widgets/containers/flex_container.js";
import FloatingButtons from "../widgets/FloatingButtons.jsx";
import GlobalMenu from "../widgets/buttons/global_menu.jsx"; import GlobalMenu from "../widgets/buttons/global_menu.jsx";
import HighlightsListWidget from "../widgets/highlights_list.js";
import LauncherContainer from "../widgets/containers/launcher_container.js";
import LeftPaneContainer from "../widgets/containers/left_pane_container.js";
import LeftPaneToggle from "../widgets/buttons/left_pane_toggle.js";
import MovePaneButton from "../widgets/buttons/move_pane_button.js";
import NoteIconWidget from "../widgets/note_icon.jsx";
import NoteList from "../widgets/collections/NoteList.jsx";
import NoteTitleWidget from "../widgets/note_title.jsx";
import NoteTreeWidget from "../widgets/note_tree.js";
import NoteWrapperWidget from "../widgets/note_wrapper.js";
import options from "../services/options.js";
import PasswordNoteSetDialog from "../widgets/dialogs/password_not_set.js";
import PromotedAttributesWidget from "../widgets/promoted_attributes.js";
import QuickSearchWidget from "../widgets/quick_search.js";
import ReadOnlyNoteInfoBar from "../widgets/ReadOnlyNoteInfoBar.jsx";
import Ribbon from "../widgets/ribbon/Ribbon.jsx";
import RightPaneContainer from "../widgets/containers/right_pane_container.js";
import RootContainer from "../widgets/containers/root_container.js";
import ScrollingContainer from "../widgets/containers/scrolling_container.js";
import ScrollPadding from "../widgets/scroll_padding.js";
import SearchResult from "../widgets/search_result.jsx";
import SharedInfo from "../widgets/shared_info.jsx";
import SpacerWidget from "../widgets/spacer.js";
import SplitNoteContainer from "../widgets/containers/split_note_container.js";
import SqlResults from "../widgets/sql_result.js"; import SqlResults from "../widgets/sql_result.js";
import SqlTableSchemas from "../widgets/sql_table_schemas.js"; import SqlTableSchemas from "../widgets/sql_table_schemas.js";
import TabRowWidget from "../widgets/tab_row.js";
import TitleBarButtons from "../widgets/title_bar_buttons.jsx"; import TitleBarButtons from "../widgets/title_bar_buttons.jsx";
import LeftPaneToggle from "../widgets/buttons/left_pane_toggle.js"; import TocWidget from "../widgets/toc.js";
import ApiLog from "../widgets/api_log.jsx"; import type { AppContext } from "../components/app_context.js";
import CloseZenModeButton from "../widgets/close_zen_button.jsx"; import type { WidgetsByParent } from "../services/bundle.js";
import SharedInfo from "../widgets/shared_info.jsx"; import UploadAttachmentsDialog from "../widgets/dialogs/upload_attachments.js";
import NoteList from "../widgets/collections/NoteList.jsx"; import utils from "../services/utils.js";
import WatchedFileUpdateStatusWidget from "../widgets/watched_file_update_status.js";
import NoteDetail from "../widgets/NoteDetail.jsx"; import NoteDetail from "../widgets/NoteDetail.jsx";
export default class DesktopLayout { export default class DesktopLayout {
@ -129,12 +131,15 @@ export default class DesktopLayout {
.child(<CreatePaneButton />) .child(<CreatePaneButton />)
) )
.child(<Ribbon />) .child(<Ribbon />)
.child(<SharedInfo />)
.child(new WatchedFileUpdateStatusWidget()) .child(new WatchedFileUpdateStatusWidget())
.child(<FloatingButtons items={DESKTOP_FLOATING_BUTTONS} />) .child(<FloatingButtons items={DESKTOP_FLOATING_BUTTONS} />)
.child( .child(
new ScrollingContainer() new ScrollingContainer()
.filling() .filling()
.child(new ContentHeader()
.child(<ReadOnlyNoteInfoBar />)
.child(<SharedInfo />)
)
.child(new PromotedAttributesWidget()) .child(new PromotedAttributesWidget())
.child(<SqlTableSchemas />) .child(<SqlTableSchemas />)
.child(<NoteDetail />) .child(<NoteDetail />)

View File

@ -1,32 +1,34 @@
import { applyModals } from "./layout_commons.js";
import { MOBILE_FLOATING_BUTTONS } from "../widgets/FloatingButtonsDefinitions.jsx";
import { useNoteContext } from "../widgets/react/hooks.jsx";
import CloseZenModeButton from "../widgets/close_zen_button.js";
import FilePropertiesTab from "../widgets/ribbon/FilePropertiesTab.jsx";
import FlexContainer from "../widgets/containers/flex_container.js"; import FlexContainer from "../widgets/containers/flex_container.js";
import NoteTitleWidget from "../widgets/note_title.js"; import FloatingButtons from "../widgets/FloatingButtons.jsx";
import QuickSearchWidget from "../widgets/quick_search.js";
import NoteTreeWidget from "../widgets/note_tree.js";
import ScreenContainer from "../widgets/mobile_widgets/screen_container.js";
import ScrollingContainer from "../widgets/containers/scrolling_container.js";
import GlobalMenuWidget from "../widgets/buttons/global_menu.js"; import GlobalMenuWidget from "../widgets/buttons/global_menu.js";
import LauncherContainer from "../widgets/containers/launcher_container.js"; import LauncherContainer from "../widgets/containers/launcher_container.js";
import RootContainer from "../widgets/containers/root_container.js";
import SharedInfoWidget from "../widgets/shared_info.js";
import PromotedAttributesWidget from "../widgets/promoted_attributes.js";
import SidebarContainer from "../widgets/mobile_widgets/sidebar_container.js";
import type AppContext from "../components/app_context.js";
import TabRowWidget from "../widgets/tab_row.js";
import MobileEditorToolbar from "../widgets/type_widgets/text/mobile_editor_toolbar.js";
import { applyModals } from "./layout_commons.js";
import FilePropertiesTab from "../widgets/ribbon/FilePropertiesTab.jsx";
import { useNoteContext } from "../widgets/react/hooks.jsx";
import FloatingButtons from "../widgets/FloatingButtons.jsx";
import { MOBILE_FLOATING_BUTTONS } from "../widgets/FloatingButtonsDefinitions.jsx";
import ToggleSidebarButton from "../widgets/mobile_widgets/toggle_sidebar_button.jsx";
import CloseZenModeButton from "../widgets/close_zen_button.js";
import NoteWrapperWidget from "../widgets/note_wrapper.js";
import MobileDetailMenu from "../widgets/mobile_widgets/mobile_detail_menu.js"; import MobileDetailMenu from "../widgets/mobile_widgets/mobile_detail_menu.js";
import MobileEditorToolbar from "../widgets/type_widgets/ckeditor/mobile_editor_toolbar.js";
import NoteList from "../widgets/collections/NoteList.jsx"; import NoteList from "../widgets/collections/NoteList.jsx";
import NoteDetail from "../widgets/NoteDetail.jsx"; import NoteTitleWidget from "../widgets/note_title.js";
import StandaloneRibbonAdapter from "../widgets/ribbon/components/StandaloneRibbonAdapter.jsx"; import ContentHeader from "../widgets/containers/content-header.js";
import NoteTreeWidget from "../widgets/note_tree.js";
import NoteWrapperWidget from "../widgets/note_wrapper.js";
import PromotedAttributesWidget from "../widgets/promoted_attributes.js";
import QuickSearchWidget from "../widgets/quick_search.js";
import ReadOnlyNoteInfoBar from "../widgets/ReadOnlyNoteInfoBar.jsx";
import RootContainer from "../widgets/containers/root_container.js";
import ScreenContainer from "../widgets/mobile_widgets/screen_container.js";
import ScrollingContainer from "../widgets/containers/scrolling_container.js";
import SearchDefinitionTab from "../widgets/ribbon/SearchDefinitionTab.jsx"; import SearchDefinitionTab from "../widgets/ribbon/SearchDefinitionTab.jsx";
import SearchResult from "../widgets/search_result.jsx"; import SearchResult from "../widgets/search_result.jsx";
import SharedInfoWidget from "../widgets/shared_info.js";
import SidebarContainer from "../widgets/mobile_widgets/sidebar_container.js";
import StandaloneRibbonAdapter from "../widgets/ribbon/components/StandaloneRibbonAdapter.jsx";
import TabRowWidget from "../widgets/tab_row.js";
import ToggleSidebarButton from "../widgets/mobile_widgets/toggle_sidebar_button.jsx";
import type AppContext from "../components/app_context.js";
import NoteDetail from "../widgets/NoteDetail.jsx";
const MOBILE_CSS = ` const MOBILE_CSS = `
<style> <style>
@ -149,13 +151,16 @@ export default class MobileLayout {
.child(<NoteTitleWidget />) .child(<NoteTitleWidget />)
.child(<MobileDetailMenu />) .child(<MobileDetailMenu />)
) )
.child(<SharedInfoWidget />)
.child(<FloatingButtons items={MOBILE_FLOATING_BUTTONS} />) .child(<FloatingButtons items={MOBILE_FLOATING_BUTTONS} />)
.child(new PromotedAttributesWidget()) .child(new PromotedAttributesWidget())
.child( .child(
new ScrollingContainer() new ScrollingContainer()
.filling() .filling()
.contentSized() .contentSized()
.child(new ContentHeader()
.child(<ReadOnlyNoteInfoBar />)
.child(<SharedInfoWidget />)
)
.child(<NoteDetail />) .child(<NoteDetail />)
.child(<NoteList media="screen" />) .child(<NoteList media="screen" />)
.child(<StandaloneRibbonAdapter component={SearchDefinitionTab} />) .child(<StandaloneRibbonAdapter component={SearchDefinitionTab} />)

View File

@ -70,6 +70,9 @@ function SingleNoteRenderer({ note, onReady }: RendererProps) {
}); });
}) })
); );
// Check custom CSS.
await loadCustomCss(note);
} }
load().then(() => requestAnimationFrame(onReady)) load().then(() => requestAnimationFrame(onReady))
@ -89,7 +92,10 @@ function CollectionRenderer({ note, onReady }: RendererProps) {
ntxId="print" ntxId="print"
highlightedTokens={null} highlightedTokens={null}
media="print" media="print"
onReady={onReady} onReady={async () => {
await loadCustomCss(note);
onReady();
}}
/>; />;
} }
@ -102,4 +108,25 @@ function Error404({ noteId }: { noteId: string }) {
) )
} }
async function loadCustomCss(note: FNote) {
const printCssNotes = await note.getRelationTargets("printCss");
let loadPromises: JQueryPromise<void>[] = [];
for (const printCssNote of printCssNotes) {
if (!printCssNote || (printCssNote.type !== "code" && printCssNote.mime !== "text/css")) continue;
const linkEl = document.createElement("link");
linkEl.href = `/api/notes/${printCssNote.noteId}/download`;
linkEl.rel = "stylesheet";
const promise = $.Deferred();
loadPromises.push(promise.promise());
linkEl.onload = () => promise.resolve();
document.head.appendChild(linkEl);
}
await Promise.allSettled(loadPromises);
}
main(); main();

View File

@ -1809,12 +1809,15 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu {
} }
.note-split { .note-split {
/* Limits the maximum width of the note */
--max-content-width: var(--preferred-max-content-width);
margin-inline-start: auto; margin-inline-start: auto;
margin-inline-end: auto; margin-inline-end: auto;
} }
.note-split.full-content-width { .note-split.full-content-width {
max-width: 999999px; --max-content-width: unset;
} }
button.close:hover { button.close:hover {
@ -2034,13 +2037,16 @@ body.zen #right-pane,
body.zen #mobile-sidebar-wrapper, body.zen #mobile-sidebar-wrapper,
body.zen .tab-row-container, body.zen .tab-row-container,
body.zen .tab-row-widget, body.zen .tab-row-widget,
body.zen .shared-info-widget,
body.zen .ribbon-container:not(:has(.classic-toolbar-widget)), body.zen .ribbon-container:not(:has(.classic-toolbar-widget)),
body.zen .ribbon-container:has(.classic-toolbar-widget) .ribbon-top-row, body.zen .ribbon-container:has(.classic-toolbar-widget) .ribbon-top-row,
body.zen .ribbon-container .ribbon-body:not(:has(.classic-toolbar-widget)), body.zen .ribbon-container .ribbon-body:not(:has(.classic-toolbar-widget)),
body.zen .note-icon-widget, body.zen .note-icon-widget,
body.zen .title-row .icon-action, body.zen .title-row .icon-action,
body.zen .promoted-attributes-widget,
body.zen .floating-buttons-children > *:not(.bx-edit-alt), body.zen .floating-buttons-children > *:not(.bx-edit-alt),
body.zen .action-button { body.zen .action-button,
body.zen .note-list-widget:not(.full-height) {
display: none !important; display: none !important;
} }
@ -2084,12 +2090,116 @@ body.zen .note-title-widget,
body.zen .note-title-widget input { body.zen .note-title-widget input {
font-size: 1rem !important; font-size: 1rem !important;
background: transparent !important; background: transparent !important;
pointer-events: none;
} }
body.zen #detail-container { body.zen #detail-container {
width: 100%; width: 100%;
} }
body.zen .note-split:not(.full-content-width) .scrolling-container {
display: flex;
flex-direction: column;
scroll-behavior: unset !important;
}
body.zen .note-split:not(.full-content-width) .note-detail {
margin: auto;
padding-bottom: 25vh;
max-width: var(--max-content-width);
width: 100%;
}
body.zen .note-split:not(.full-content-width) .scroll-padding-widget {
display: none;
}
body.zen .note-split.type-text {
position: relative;
font-size: 1.15em;
}
body.zen:not(.backdrop-effects-disabled) .note-split.type-text .title-row {
--start-color: var(--main-background-color);
position: absolute;
width: 100%;
background: linear-gradient(var(--start-color) 30%, transparent 100%);
z-index: 1000;
}
@supports (background: color-mix(in srgb, white, transparent)) {
body.zen .note-split.type-text .title-row {
--start-color: color-mix(in srgb, var(--main-background-color), transparent 10%);
}
}
body.zen .note-split.type-text .scrolling-container {
--padding-bottom: 130px; /* Should be enough to avoid caret being hidden by the formatting toolbar */
/* (Usually) keeps the caret above the fixed toolbar */
scroll-padding-bottom: var(--padding-bottom);
}
body.zen:not(.backdrop-effects-disabled) .note-split.type-text .scrolling-container {
--padding-top: 50px; /* Should be enough to cover the title row */
padding-top: var(--padding-top);
scroll-padding-top: var(--padding-top);
}
/* Fixed formatting toolbar */
body.zen .note-split .ribbon-container {
position: fixed;
left: 0;
bottom: 20px;
width: 100%;
z-index: 1000;
opacity: 0; /* Hidden unless the current note split is focused */
pointer-events: none;
transition: opacity 100ms linear;
}
body.zen .note-split:focus-within .ribbon-container {
opacity: 1; /* Show when the note split is focused */
}
body.zen .note-split .ribbon-container .ribbon-body {
border: 0;
}
body.zen .note-split .ribbon-container .classic-toolbar-widget {
margin: auto;
width: fit-content;
box-shadow: 0px 10px 20px rgba(0, 0, 0, .1);
border-radius: 8px;
border: 1px solid var(--main-border-color);
padding: 4px;
background: var(--menu-background-color);
}
body.zen .note-split:focus-within .ribbon-container .classic-toolbar-widget {
pointer-events: all;
}
@media (max-width: 1300px) {
body.zen .note-split .ribbon-container .classic-toolbar-widget {
/* Set the toolbar to full with */
width: 100%;
}
body.zen .classic-toolbar-widget .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_se,
body.zen .classic-toolbar-widget .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_sw,
body.zen .classic-toolbar-widget .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_smw,
body.zen .classic-toolbar-widget .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_sme,
body.zen .classic-toolbar-widget .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_s {
/* Force toolbar items overflow dropdowns open upwards */
top: auto;
bottom: 100%;
}
}
/* Content renderer */ /* Content renderer */
footer.file-footer, footer.file-footer,

View File

@ -15,7 +15,7 @@
--native-titlebar-background: #00000000; --native-titlebar-background: #00000000;
--window-background-color-bgfx: transparent; /* When background effects enabled */ --window-background-color-bgfx: transparent; /* When background effects enabled */
--main-background-color: #272727; --main-background-color: #242424;
--main-text-color: #ccc; --main-text-color: #ccc;
--main-border-color: #454545; --main-border-color: #454545;
--subtle-border-color: #313131; --subtle-border-color: #313131;
@ -166,6 +166,9 @@
--protected-session-active-icon-color: #8edd8e; --protected-session-active-icon-color: #8edd8e;
--sync-status-error-pulse-color: #f47871; --sync-status-error-pulse-color: #f47871;
--center-pane-vert-layout-background-color-bgfx: #0c0c0c69;
--center-pane-horiz-layout-background-color-bgfx: #1e1e1ec7;
--right-pane-heading-color: gray; --right-pane-heading-color: gray;
--root-background: var(--left-pane-background-color); --root-background: var(--left-pane-background-color);
@ -192,8 +195,8 @@
--badge-background-color: #ffffff1a; --badge-background-color: #ffffff1a;
--badge-text-color: var(--muted-text-color); --badge-text-color: var(--muted-text-color);
--promoted-attribute-card-background-color: var(--card-background-color); --promoted-attribute-card-background-color: #ffffff21;
--promoted-attribute-card-shadow-color: #000000b3; --promoted-attribute-card-shadow: none;
--floating-button-shadow-color: #00000080; --floating-button-shadow-color: #00000080;
--floating-button-background-color: #494949d2; --floating-button-background-color: #494949d2;
@ -208,6 +211,8 @@
--floating-button-hide-button-background: #00000029; --floating-button-hide-button-background: #00000029;
--floating-button-hide-button-color: #ffffff63; --floating-button-hide-button-color: #ffffff63;
--right-pane-background-color: var(--main-background-color);
--right-pane-background-color-bgfx: #0c0c0c24; /* Only for the vertical layout */
--right-pane-item-hover-background: #ffffff26; --right-pane-item-hover-background: #ffffff26;
--right-pane-item-hover-color: white; --right-pane-item-hover-color: white;
@ -227,8 +232,8 @@
--card-background-color: #ffffff12; --card-background-color: #ffffff12;
--card-background-hover-color: #3c3c3c; --card-background-hover-color: #3c3c3c;
--card-background-press-color: #464646; --card-background-press-color: #464646;
--card-border-color: #222222; --card-border-color: transparent;
--card-box-shadow: 0 0 12px rgba(0, 0, 0, 0.15); --card-box-shadow: none;
--calendar-color: var(--menu-text-color); --calendar-color: var(--menu-text-color);
--calendar-weekday-labels-color: var(--muted-text-color); --calendar-weekday-labels-color: var(--muted-text-color);
@ -295,3 +300,9 @@ body ::-webkit-calendar-picker-indicator {
body .todo-list input[type="checkbox"]:not(:checked):before { body .todo-list input[type="checkbox"]:not(:checked):before {
border-color: var(--muted-text-color) !important; border-color: var(--muted-text-color) !important;
} }
.tinted-quick-edit-dialog {
--modal-background-color: hsl(var(--custom-color-hue), 8.8%, 11.2%);
--modal-border-color: hsl(var(--custom-color-hue), 9.4%, 25.1%);
--promoted-attribute-card-background-color: hsl(var(--custom-color-hue), 13.2%, 20.8%);
}

View File

@ -159,6 +159,9 @@
--protected-session-active-icon-color: #16b516; --protected-session-active-icon-color: #16b516;
--sync-status-error-pulse-color: #ff5528; --sync-status-error-pulse-color: #ff5528;
--center-pane-vert-layout-background-color-bgfx: #ffffff75;
--center-pane-horiz-layout-background-color-bgfx: #ffffffd6;
--right-pane-heading-color: gray; --right-pane-heading-color: gray;
--root-background: var(--left-pane-background-color); --root-background: var(--left-pane-background-color);
@ -180,13 +183,13 @@
--inactive-tab-hover-background-color: #00000016; --inactive-tab-hover-background-color: #00000016;
--inactive-tab-text-color: #4e4e4e; --inactive-tab-text-color: #4e4e4e;
--alert-bar-background: #32637b29; --alert-bar-background: #f9cf2b29;
--badge-background-color: #00000011; --badge-background-color: #00000011;
--badge-text-color: var(--muted-text-color); --badge-text-color: var(--muted-text-color);
--promoted-attribute-card-background-color: var(--card-background-color); --promoted-attribute-card-background-color: #00000014;
--promoted-attribute-card-shadow-color: #00000033; --promoted-attribute-card-shadow: none;
--floating-button-shadow-color: #00000042; --floating-button-shadow-color: #00000042;
--floating-button-background-color: #eaeaeacc; --floating-button-background-color: #eaeaeacc;
@ -207,6 +210,8 @@
--new-tab-button-hover-background: white; --new-tab-button-hover-background: white;
--new-tab-button-hover-color: black; --new-tab-button-hover-color: black;
--right-pane-background-color: var(--main-background-color);
--right-pane-background-color-bgfx: var(--center-pane-vert-layout-background-color-bgfx); /* Only for the vertical layout */
--right-pane-item-hover-background: #ececec; --right-pane-item-hover-background: #ececec;
--right-pane-item-hover-color: inherit; --right-pane-item-hover-color: inherit;
@ -223,12 +228,12 @@
--code-block-box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.1), 0px 0px 2px rgba(0, 0, 0, 0.2); --code-block-box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.1), 0px 0px 2px rgba(0, 0, 0, 0.2);
--card-background-color: var(--accented-background-color); --card-background-color: #0000000d;
--card-background-hover-color: #f9f9f9; --card-background-hover-color: #f9f9f9;
--card-background-press-color: #efefef; --card-background-press-color: #efefef;
--card-border-color: #eaeaea; --card-border-color: transparent;
--card-shadow-color: rgba(0, 0, 0, 0.1); --card-shadow-color: rgba(0, 0, 0, 0.1);
--card-box-shadow: 0 0 12px var(--card-shadow-color); --card-box-shadow: none;
--calendar-color: var(--menu-text-color); --calendar-color: var(--menu-text-color);
--calendar-weekday-labels-color: var(--muted-text-color); --calendar-weekday-labels-color: var(--muted-text-color);
@ -271,3 +276,9 @@
* This value is unset for gray tones. */ * This value is unset for gray tones. */
--custom-bg-color: hsl(var(--custom-color-hue), 37%, 89%, 1); --custom-bg-color: hsl(var(--custom-color-hue), 37%, 89%, 1);
} }
.tinted-quick-edit-dialog {
--modal-background-color: hsl(var(--custom-color-hue), 56%, 96%);
--modal-border-color: hsl(var(--custom-color-hue), 33%, 41%);
--promoted-attribute-card-background-color: hsl(var(--custom-color-hue), 40%, 88%);
}

View File

@ -82,6 +82,7 @@
/* Theme capabilities */ /* Theme capabilities */
--tab-note-icons: true; --tab-note-icons: true;
--allow-background-effects: true;
/* To ensure that a tree item's custom color remains sufficiently contrasted and readable, /* To ensure that a tree item's custom color remains sufficiently contrasted and readable,
* the color is adjusted based on the current color scheme (light or dark). The lightness * the color is adjusted based on the current color scheme (light or dark). The lightness
@ -131,7 +132,8 @@ body.mobile .dropdown-menu .dropdown-menu {
body.desktop .dropdown-menu::before, body.desktop .dropdown-menu::before,
:root .ck.ck-dropdown__panel::before, :root .ck.ck-dropdown__panel::before,
:root .excalidraw .popover::before { :root .excalidraw .popover::before,
body.zen .note-split .ribbon-container .classic-toolbar-widget::before {
content: ""; content: "";
backdrop-filter: var(--dropdown-backdrop-filter); backdrop-filter: var(--dropdown-backdrop-filter);
border-radius: var(--dropdown-border-radius); border-radius: var(--dropdown-border-radius);

View File

@ -258,11 +258,6 @@
border-inline-start: 1px solid var(--ck-color-toolbar-border); border-inline-start: 1px solid var(--ck-color-toolbar-border);
} }
/* The last separator of the toolbar */
:root .classic-toolbar-widget .ck.ck-toolbar__separator:last-of-type {
flex-grow: 1;
}
/* Heading dropdown */ /* Heading dropdown */
:root .ck.ck-dropdown.ck-heading-dropdown .ck-dropdown__panel .ck-list__item { :root .ck.ck-dropdown.ck-heading-dropdown .ck-dropdown__panel .ck-list__item {

View File

@ -148,7 +148,7 @@ div.note-detail-empty {
--options-card-min-width: 500px; --options-card-min-width: 500px;
--options-card-max-width: 900px; --options-card-max-width: 900px;
--options-card-padding: 17px; --options-card-padding: 17px;
--options-title-font-size: 1rem; --options-title-font-size: .75rem;
--options-title-offset: 13px; --options-title-offset: 13px;
} }
/* Create a gap at the top of the option pages */ /* Create a gap at the top of the option pages */
@ -173,16 +173,19 @@ div.note-detail-empty {
} }
.options-section:not(.tn-no-card) { .options-section:not(.tn-no-card) {
margin: auto; margin-bottom: calc(var(--options-title-offset) + 26px) !important;
border-radius: 12px;
border: 1px solid var(--card-border-color) !important;
box-shadow: var(--card-box-shadow); box-shadow: var(--card-box-shadow);
border: 1px solid var(--card-border-color) !important;
border-radius: 8px;
background: var(--card-background-color); background: var(--card-background-color);
padding: var(--options-card-padding); padding: var(--options-card-padding);
margin-bottom: calc(var(--options-title-offset) + 26px) !important;
} }
body.desktop .option-section:not(.tn-no-card) { body.prefers-centered-content .options-section:not(.tn-no-card) {
margin-inline: auto;
}
body.desktop .options-section:not(.tn-no-card) {
min-width: var(--options-card-min-width); min-width: var(--options-card-min-width);
max-width: var(--options-card-max-width); max-width: var(--options-card-max-width);
} }
@ -193,9 +196,16 @@ body.desktop .option-section:not(.tn-no-card) {
padding-bottom: var(--default-padding); padding-bottom: var(--default-padding);
} }
.options-section:not(.tn-no-card) h4,
.options-section:not(.tn-no-card) h5 {
text-transform: uppercase;
letter-spacing: .4pt;
}
.options-section:not(.tn-no-card) h4 { .options-section:not(.tn-no-card) h4 {
font-size: var(--options-title-font-size); font-size: var(--options-title-font-size);
font-weight: bold; font-weight: 600;
color: var(--launcher-pane-text-color); color: var(--launcher-pane-text-color);
margin-top: calc(-1 * var(--options-card-padding) - var(--options-title-font-size) - var(--options-title-offset)) !important; margin-top: calc(-1 * var(--options-card-padding) - var(--options-title-font-size) - var(--options-title-offset)) !important;
margin-bottom: calc(var(--options-title-offset) + var(--options-card-padding)) !important; margin-bottom: calc(var(--options-title-offset) + var(--options-card-padding)) !important;

View File

@ -34,6 +34,7 @@
div.promoted-attributes-container { div.promoted-attributes-container {
margin-top: 8px; margin-top: 8px;
margin-bottom: 8px; margin-bottom: 8px;
margin-inline-start: 12px;
} }
/* /*

View File

@ -8,7 +8,7 @@
} }
:root { :root {
--dropdown-backdrop-filter: blur(10px) saturate(6); --dropdown-backdrop-filter: blur(20px) saturate(6);
--dropdown-border-radius: 10px; --dropdown-border-radius: 10px;
} }
@ -35,30 +35,52 @@ body.mobile {
} }
/* #region Mica */ /* #region Mica */
body.background-effects.platform-win32 { body.background-effects.platform-win32 {
/* Quirk: --background-material is read before "theme-supports-background-effects" class
* is applied. Apply the matterial even if the theme doesn't support it. */
--background-material: tabbed; --background-material: tabbed;
}
body.background-effects.theme-supports-background-effects.platform-win32 {
--launcher-pane-horiz-border-color: var(--launcher-pane-horiz-border-color-bgfx); --launcher-pane-horiz-border-color: var(--launcher-pane-horiz-border-color-bgfx);
--launcher-pane-horiz-background-color: var(--launcher-pane-horiz-background-color-bgfx); --launcher-pane-horiz-background-color: var(--launcher-pane-horiz-background-color-bgfx);
--launcher-pane-vert-background-color: var(--launcher-pane-vert-background-color-bgfx); --launcher-pane-vert-background-color: var(--launcher-pane-vert-background-color-bgfx);
--tab-background-color: var(--window-background-color-bgfx); --tab-background-color: var(--window-background-color-bgfx);
--new-tab-button-background: var(--window-background-color-bgfx); --new-tab-button-background: var(--window-background-color-bgfx);
--active-tab-background-color: var(--launcher-pane-horiz-background-color); --active-tab-background-color: var(--launcher-pane-horiz-background-color);
--root-background: transparent;
} }
body.background-effects.platform-win32.layout-vertical { body.background-effects.platform-win32.layout-vertical {
--left-pane-background-color: var(--window-background-color-bgfx);
--background-material: mica; --background-material: mica;
} }
body.background-effects.platform-win32, body.background-effects.theme-supports-background-effects.platform-win32.layout-vertical {
body.background-effects.platform-win32 #root-widget { --left-pane-background-color: var(--window-background-color-bgfx);
--center-pane-background-color-bgfx: var(--center-pane-vert-layout-background-color-bgfx);
--right-pane-background-color: var(--right-pane-background-color-bgfx);
}
body.background-effects.theme-supports-background-effects.platform-win32.layout-horizontal {
--center-pane-background-color-bgfx: var(--center-pane-horiz-layout-background-color-bgfx);
}
body.background-effects.theme-supports-background-effects.platform-win32,
body.background-effects.theme-supports-background-effects.platform-win32 #root-widget {
background: var(--window-background-color-bgfx) !important; background: var(--window-background-color-bgfx) !important;
} }
body.background-effects.platform-win32.layout-horizontal #horizontal-main-container, body.background-effects.theme-supports-background-effects.platform-win32.layout-horizontal #horizontal-main-container,
body.background-effects.platform-win32.layout-vertical #vertical-main-container { body.background-effects.theme-supports-background-effects.platform-win32.layout-vertical #vertical-main-container {
background-color: var(--root-background); background-color: var(--root-background);
} }
/* Note split with background effects */
body.background-effects.theme-supports-background-effects.platform-win32 #center-pane .note-split.bgfx {
--note-split-background-color: var(--center-pane-background-color-bgfx);
}
/* #endregion */ /* #endregion */
/* Matches when the left pane is collapsed */ /* Matches when the left pane is collapsed */
@ -72,9 +94,21 @@ body.layout-vertical #horizontal-main-container.left-pane-hidden #launcher-pane.
border-inline-end: 2px solid var(--left-pane-collapsed-border-color); border-inline-end: 2px solid var(--left-pane-collapsed-border-color);
} }
body.background-effects.zen #root-widget { /*
--main-background-color: transparent; * Zen mode
--root-background: transparent; */
@keyframes zen-formatting-toolbar-entrance {
from {
transform: translateY(200%);
} to {
transform: translateY(0);
}
}
body.zen .note-split .ribbon-container .classic-toolbar-widget {
position: relative;
animation: zen-formatting-toolbar-entrance 300ms ease-out;
} }
/* /*
@ -1171,23 +1205,18 @@ body.layout-vertical .tab-row-widget-is-sorting .note-tab.note-tab-is-dragging .
* CENTER PANE * CENTER PANE
*/ */
#center-pane { /* The first visible note split */
background: var(--main-background-color); .vertical-layout #center-pane .note-split:not(.visible ~ .visible) {
}
.vertical-layout #center-pane {
border-radius: var(--center-pane-border-radius) 0 0 0; border-radius: var(--center-pane-border-radius) 0 0 0;
} }
.note-split { #center-pane .note-split {
padding-top: 2px; padding-top: 2px;
animation: note-entrance 100ms linear; background-color: var(--note-split-background-color, var(--main-background-color));
/* will-change: opacity; -- causes some weird artifacts to the note menu in split view */
} }
.split-note-container-widget > .gutter { body:not(.background-effects) #center-pane .note-split {
background: var(--root-background) !important; animation: note-entrance 100ms linear;
transition: background 150ms ease-out;
} }
/* /*
@ -1200,9 +1229,9 @@ body.layout-vertical .tab-row-widget-is-sorting .note-tab.note-tab-is-dragging .
@keyframes note-entrance { @keyframes note-entrance {
from { from {
opacity: 0; filter: opacity(0);
} to { } to {
opacity: 1; filter: opacity(1);
} }
} }
@ -1328,8 +1357,7 @@ div.promoted-attribute-cell {
--pa-card-padding-inline-end: 2px; --pa-card-padding-inline-end: 2px;
--input-background-color: transparent; --input-background-color: transparent;
box-shadow: 1px 1px 2px var(--promoted-attribute-card-shadow-color); box-shadow: var(--promoted-attribute-card-shadow);
display: inline-flex; display: inline-flex;
margin: 0; margin: 0;
border-radius: 8px; border-radius: 8px;
@ -1716,7 +1744,7 @@ div.find-replace-widget div.find-widget-found-wrapper > span {
*/ */
#right-pane { #right-pane {
background: var(--main-background-color); background: var(--right-pane-background-color);
} }
#right-pane div.card-header { #right-pane div.card-header {

View File

@ -520,9 +520,7 @@
"max_content_width": { "max_content_width": {
"max_width_unit": "بكسل", "max_width_unit": "بكسل",
"title": "عرض المحتوى", "title": "عرض المحتوى",
"reload_button": "اعادة تحميل الواجهة", "max_width_label": "اقصى عرض للمحتوى"
"max_width_label": "اقصى عرض للمحتوى",
"reload_description": "تغييرات من خيارات المظهر"
}, },
"native_title_bar": { "native_title_bar": {
"enabled": "مفعل", "enabled": "مفعل",

View File

@ -39,7 +39,10 @@
"help_on_tree_prefix": "有关树前缀的帮助", "help_on_tree_prefix": "有关树前缀的帮助",
"prefix": "前缀: ", "prefix": "前缀: ",
"save": "保存", "save": "保存",
"branch_prefix_saved": "分支前缀已保存。" "branch_prefix_saved": "分支前缀已保存。",
"edit_branch_prefix_multiple": "编辑 {{count}} 个分支的前缀",
"branch_prefix_saved_multiple": "已为 {{count}} 个分支保存分支前缀。",
"affected_branches": "受影响的分支 {{count}}:"
}, },
"bulk_actions": { "bulk_actions": {
"bulk_actions": "批量操作", "bulk_actions": "批量操作",
@ -1107,9 +1110,6 @@
"title": "内容宽度", "title": "内容宽度",
"default_description": "Trilium默认会限制内容的最大宽度以提高在宽屏中全屏时的可读性。", "default_description": "Trilium默认会限制内容的最大宽度以提高在宽屏中全屏时的可读性。",
"max_width_label": "内容最大宽度(像素)", "max_width_label": "内容最大宽度(像素)",
"apply_changes_description": "要应用内容宽度更改,请点击",
"reload_button": "重载前端",
"reload_description": "来自外观选项的更改",
"max_width_unit": "像素" "max_width_unit": "像素"
}, },
"native_title_bar": { "native_title_bar": {
@ -1917,7 +1917,7 @@
}, },
"custom_date_time_format": { "custom_date_time_format": {
"title": "自定义日期/时间格式", "title": "自定义日期/时间格式",
"description": "通过<shortcut />或工具栏的方式可自定义日期和时间格式,有关日期/时间格式字符串中各个字符的含义,请参阅<doc>Day.js docs</doc>。", "description": "自定义通过 <shortcut /> 或工具栏插入的日期和时间格式。有关日期/时间格式字符串中各个字符的含义,请参阅<doc>Day.js docs</doc>。",
"format_string": "日期/时间格式字符串:", "format_string": "日期/时间格式字符串:",
"formatted_time": "格式化后日期/时间:" "formatted_time": "格式化后日期/时间:"
}, },
@ -2079,5 +2079,8 @@
"edit-slide": "编辑此幻灯片", "edit-slide": "编辑此幻灯片",
"start-presentation": "开始演示", "start-presentation": "开始演示",
"slide-overview": "切换幻灯片概览" "slide-overview": "切换幻灯片概览"
},
"calendar_view": {
"delete_note": "删除笔记..."
} }
} }

View File

@ -1104,9 +1104,6 @@
"title": "Inhaltsbreite", "title": "Inhaltsbreite",
"default_description": "Trilium begrenzt standardmäßig die maximale Inhaltsbreite, um die Lesbarkeit für maximierte Bildschirme auf Breitbildschirmen zu verbessern.", "default_description": "Trilium begrenzt standardmäßig die maximale Inhaltsbreite, um die Lesbarkeit für maximierte Bildschirme auf Breitbildschirmen zu verbessern.",
"max_width_label": "Maximale Inhaltsbreite in Pixel", "max_width_label": "Maximale Inhaltsbreite in Pixel",
"apply_changes_description": "Um Änderungen an der Inhaltsbreite anzuwenden, klicke auf",
"reload_button": "Frontend neu laden",
"reload_description": "Änderungen an den Darstellungsoptionen",
"max_width_unit": "Pixel" "max_width_unit": "Pixel"
}, },
"native_title_bar": { "native_title_bar": {

View File

@ -1111,9 +1111,7 @@
"default_description": "Trilium by default limits max content width to improve readability for maximized screens on wide screens.", "default_description": "Trilium by default limits max content width to improve readability for maximized screens on wide screens.",
"max_width_label": "Max content width", "max_width_label": "Max content width",
"max_width_unit": "pixels", "max_width_unit": "pixels",
"apply_changes_description": "To apply content width changes, click on", "centerContent": "Keep content centered"
"reload_button": "reload frontend",
"reload_description": "changes from appearance options"
}, },
"native_title_bar": { "native_title_bar": {
"title": "Native Title Bar (requires app restart)", "title": "Native Title Bar (requires app restart)",
@ -1639,6 +1637,12 @@
"shared_locally": "This note is shared locally on {{- link}}.", "shared_locally": "This note is shared locally on {{- link}}.",
"help_link": "For help visit <a href=\"https://triliumnext.github.io/Docs/Wiki/sharing.html\">wiki</a>." "help_link": "For help visit <a href=\"https://triliumnext.github.io/Docs/Wiki/sharing.html\">wiki</a>."
}, },
"read-only-info": {
"read-only-note": "Currently viewing a read-only note.",
"auto-read-only-note": "This note is shown in a read-only mode for faster loading.",
"auto-read-only-learn-more": "Learn more",
"edit-note": "Edit note"
},
"note_types": { "note_types": {
"text": "Text", "text": "Text",
"code": "Code", "code": "Code",

View File

@ -1107,10 +1107,7 @@
"title": "Ancho del contenido", "title": "Ancho del contenido",
"default_description": "Trilium limita de forma predeterminada el ancho máximo del contenido para mejorar la legibilidad de ventanas maximizadas en pantallas anchas.", "default_description": "Trilium limita de forma predeterminada el ancho máximo del contenido para mejorar la legibilidad de ventanas maximizadas en pantallas anchas.",
"max_width_label": "Ancho máximo del contenido en píxeles", "max_width_label": "Ancho máximo del contenido en píxeles",
"max_width_unit": "píxeles", "max_width_unit": "píxeles"
"apply_changes_description": "Para aplicar cambios en el ancho del contenido, haga clic en",
"reload_button": "recargar la interfaz",
"reload_description": "cambios desde las opciones de apariencia"
}, },
"native_title_bar": { "native_title_bar": {
"title": "Barra de título nativa (requiere reiniciar la aplicación)", "title": "Barra de título nativa (requiere reiniciar la aplicación)",
@ -1592,7 +1589,7 @@
"tree-context-menu": { "tree-context-menu": {
"open-in-a-new-tab": "Abrir en nueva pestaña", "open-in-a-new-tab": "Abrir en nueva pestaña",
"open-in-a-new-split": "Abrir en nueva división", "open-in-a-new-split": "Abrir en nueva división",
"insert-note-after": "Insertar nota después de", "insert-note-after": "Insertar nota contigua",
"insert-child-note": "Insertar subnota", "insert-child-note": "Insertar subnota",
"delete": "Eliminar", "delete": "Eliminar",
"search-in-subtree": "Buscar en subárbol", "search-in-subtree": "Buscar en subárbol",

View File

@ -1106,9 +1106,6 @@
"title": "Largeur du contenu", "title": "Largeur du contenu",
"default_description": "Trilium limite par défaut la largeur maximale du contenu pour améliorer la lisibilité sur des écrans larges.", "default_description": "Trilium limite par défaut la largeur maximale du contenu pour améliorer la lisibilité sur des écrans larges.",
"max_width_label": "Largeur maximale du contenu en pixels", "max_width_label": "Largeur maximale du contenu en pixels",
"apply_changes_description": "Pour appliquer les modifications de largeur du contenu, cliquez sur",
"reload_button": "recharger l'interface",
"reload_description": "changements par rapport aux options d'apparence",
"max_width_unit": "Pixels" "max_width_unit": "Pixels"
}, },
"native_title_bar": { "native_title_bar": {

View File

@ -1570,10 +1570,7 @@
"title": "Larghezza del contenuto", "title": "Larghezza del contenuto",
"default_description": "Per impostazione predefinita, Trilium limita la larghezza massima del contenuto per migliorare la leggibilità sugli schermi più grandi.", "default_description": "Per impostazione predefinita, Trilium limita la larghezza massima del contenuto per migliorare la leggibilità sugli schermi più grandi.",
"max_width_label": "Larghezza massima del contenuto", "max_width_label": "Larghezza massima del contenuto",
"max_width_unit": "pixel", "max_width_unit": "pixel"
"apply_changes_description": "Per applicare le modifiche alla larghezza del contenuto, fare clic su",
"reload_button": "ricarica frontend",
"reload_description": "modifiche dalle opzioni di aspetto"
}, },
"native_title_bar": { "native_title_bar": {
"title": "Barra del titolo nativa (richiede il riavvio dell'app)", "title": "Barra del titolo nativa (richiede il riavvio dell'app)",

View File

@ -39,7 +39,10 @@
"edit_branch_prefix": "ブランチ接頭辞の編集", "edit_branch_prefix": "ブランチ接頭辞の編集",
"help_on_tree_prefix": "ツリー接頭辞に関するヘルプ", "help_on_tree_prefix": "ツリー接頭辞に関するヘルプ",
"prefix": "接頭辞: ", "prefix": "接頭辞: ",
"branch_prefix_saved": "ブランチの接頭辞が保存されました。" "branch_prefix_saved": "ブランチの接頭辞が保存されました。",
"edit_branch_prefix_multiple": "{{count}} ブランチのブランチ接頭辞を編集",
"branch_prefix_saved_multiple": "{{count}} 個のブランチのブランチ接頭辞が保存されました。",
"affected_branches": "影響を受けるブランチ {{count}}:"
}, },
"global_menu": { "global_menu": {
"menu": "メニュー", "menu": "メニュー",
@ -830,13 +833,10 @@
"theme_defined": "テーマが定義されました" "theme_defined": "テーマが定義されました"
}, },
"max_content_width": { "max_content_width": {
"reload_button": "フロントエンドをリロード",
"title": "コンテンツ幅", "title": "コンテンツ幅",
"default_description": "Triliumは、ワイドスクリーンで最大化された画面での可読性を向上させるために、デフォルトでコンテンツの最大幅を制限しています。", "default_description": "Triliumは、ワイドスクリーンで最大化された画面での可読性を向上させるために、デフォルトでコンテンツの最大幅を制限しています。",
"max_width_label": "最大コンテンツ幅", "max_width_label": "最大コンテンツ幅",
"max_width_unit": "ピクセル", "max_width_unit": "ピクセル"
"apply_changes_description": "コンテンツ幅の変更を適用するには、クリックしてください",
"reload_description": "外観設定から変更"
}, },
"theme": { "theme": {
"title": "アプリのテーマ", "title": "アプリのテーマ",
@ -2079,5 +2079,8 @@
"edit-slide": "このスライドを編集", "edit-slide": "このスライドを編集",
"start-presentation": "プレゼンテーションを開始", "start-presentation": "プレゼンテーションを開始",
"slide-overview": "スライドの概要を切り替え" "slide-overview": "スライドの概要を切り替え"
},
"calendar_view": {
"delete_note": "ノートを削除..."
} }
} }

View File

@ -1464,10 +1464,7 @@
"title": "Szerokość zawartości", "title": "Szerokość zawartości",
"default_description": "Trilium domyślnie ogranicza maksymalną szerokość zawartości, aby poprawić czytelność na zmaksymalizowanych ekranach o dużej szerokości.", "default_description": "Trilium domyślnie ogranicza maksymalną szerokość zawartości, aby poprawić czytelność na zmaksymalizowanych ekranach o dużej szerokości.",
"max_width_label": "Maksymalna szerokość zawartości", "max_width_label": "Maksymalna szerokość zawartości",
"max_width_unit": "piksele", "max_width_unit": "piksele"
"apply_changes_description": "Aby zastosować zmiany szerokości zawartości, kliknij na",
"reload_button": "przeładuj frontend",
"reload_description": "zmiany z opcji wyglądu"
}, },
"native_title_bar": { "native_title_bar": {
"title": "Natywny pasek tytułu (wymaga ponownego uruchomienia aplikacji)", "title": "Natywny pasek tytułu (wymaga ponownego uruchomienia aplikacji)",

View File

@ -1082,10 +1082,7 @@
"title": "Largura do Conteúdo", "title": "Largura do Conteúdo",
"default_description": "Por padrão, o Trilium limita a largura máxima do conteúdo para melhorar a legibilidade em janelas maximizadas em ecrãs largos.", "default_description": "Por padrão, o Trilium limita a largura máxima do conteúdo para melhorar a legibilidade em janelas maximizadas em ecrãs largos.",
"max_width_label": "Largura máxima do conteúdo", "max_width_label": "Largura máxima do conteúdo",
"max_width_unit": "pixels", "max_width_unit": "pixels"
"apply_changes_description": "Para aplicar as alterações de largura do conteúdo, clique em",
"reload_button": "recarregar frontend",
"reload_description": "alterações de opções de aparência"
}, },
"native_title_bar": { "native_title_bar": {
"title": "Barra de Título Nativa (requer recarregar a app)", "title": "Barra de Título Nativa (requer recarregar a app)",

View File

@ -1304,9 +1304,6 @@
"title": "Largura do Conteúdo", "title": "Largura do Conteúdo",
"max_width_label": "Largura máxima do conteúdo", "max_width_label": "Largura máxima do conteúdo",
"max_width_unit": "pixels", "max_width_unit": "pixels",
"apply_changes_description": "Para aplicar as alterações de largura do conteúdo, clique em",
"reload_button": "recarregar frontend",
"reload_description": "alterações de opções de aparência",
"default_description": "Por padrão, o Trilium limita a largura máxima do conteúdo para melhorar a legibilidade em janelas maximizadas em telas wide." "default_description": "Por padrão, o Trilium limita a largura máxima do conteúdo para melhorar a legibilidade em janelas maximizadas em telas wide."
}, },
"native_title_bar": { "native_title_bar": {

View File

@ -796,12 +796,9 @@
"modal_body_text": "Din cauza limitărilor la nivel de navigator, nu este posibilă citirea clipboard-ului din JavaScript. Inserați Markdown-ul pentru a-l importa în caseta de mai jos și dați clic pe butonul Import" "modal_body_text": "Din cauza limitărilor la nivel de navigator, nu este posibilă citirea clipboard-ului din JavaScript. Inserați Markdown-ul pentru a-l importa în caseta de mai jos și dați clic pe butonul Import"
}, },
"max_content_width": { "max_content_width": {
"apply_changes_description": "Pentru a aplica schimbările de lățime a conținutului, dați click pe",
"default_description": "În mod implicit Trilium limitează lățimea conținutului pentru a îmbunătăți lizibilitatea pentru ferestrele maximizate pe ecrane late.", "default_description": "În mod implicit Trilium limitează lățimea conținutului pentru a îmbunătăți lizibilitatea pentru ferestrele maximizate pe ecrane late.",
"max_width_label": "Lungimea maximă a conținutului", "max_width_label": "Lungimea maximă a conținutului",
"max_width_unit": "pixeli", "max_width_unit": "pixeli",
"reload_button": "reîncarcă interfața",
"reload_description": "schimbări din opțiunile de afișare",
"title": "Lățime conținut" "title": "Lățime conținut"
}, },
"mobile_detail_menu": { "mobile_detail_menu": {

View File

@ -1203,11 +1203,8 @@
"max_content_width": { "max_content_width": {
"max_width_unit": "пикселей", "max_width_unit": "пикселей",
"title": "Ширина контентной области", "title": "Ширина контентной области",
"reload_button": "перезагрузить интерфейс",
"default_description": "Trilium по умолчанию ограничивает максимальную ширину контента, чтобы улучшить читаемость на широких экранах.", "default_description": "Trilium по умолчанию ограничивает максимальную ширину контента, чтобы улучшить читаемость на широких экранах.",
"max_width_label": "Максимальная ширина контентной области", "max_width_label": "Максимальная ширина контентной области"
"apply_changes_description": "Чтобы применить изменения, нажмите на",
"reload_description": "изменения в параметрах внешнего вида"
}, },
"native_title_bar": { "native_title_bar": {
"enabled": "включено", "enabled": "включено",

View File

@ -39,7 +39,10 @@
"help_on_tree_prefix": "有關樹前綴的說明", "help_on_tree_prefix": "有關樹前綴的說明",
"prefix": "前綴: ", "prefix": "前綴: ",
"save": "儲存", "save": "儲存",
"branch_prefix_saved": "已儲存分支前綴。" "branch_prefix_saved": "已儲存分支前綴。",
"edit_branch_prefix_multiple": "編輯 {{count}} 個分支的前綴",
"branch_prefix_saved_multiple": "已為 {{count}} 個分支儲存分支前綴。",
"affected_branches": "受影響的分支 ({{count}}):"
}, },
"bulk_actions": { "bulk_actions": {
"bulk_actions": "批次操作", "bulk_actions": "批次操作",
@ -1104,9 +1107,6 @@
"title": "內容寬度", "title": "內容寬度",
"default_description": "Trilium 預設會限制內容的最大寬度以提高在寬螢幕中全螢幕時的可讀性。", "default_description": "Trilium 預設會限制內容的最大寬度以提高在寬螢幕中全螢幕時的可讀性。",
"max_width_label": "內容最大寬度(像素)", "max_width_label": "內容最大寬度(像素)",
"apply_changes_description": "要套用內容寬度更改,請點擊",
"reload_button": "重新載入前端",
"reload_description": "來自外觀選項的更改",
"max_width_unit": "像素" "max_width_unit": "像素"
}, },
"native_title_bar": { "native_title_bar": {
@ -2079,5 +2079,8 @@
"edit-slide": "編輯此投影片", "edit-slide": "編輯此投影片",
"start-presentation": "開始簡報", "start-presentation": "開始簡報",
"slide-overview": "切換投影片概覽" "slide-overview": "切換投影片概覽"
},
"calendar_view": {
"delete_note": "刪除筆記…"
} }
} }

View File

@ -1204,10 +1204,7 @@
"title": "Ширина вмісту", "title": "Ширина вмісту",
"default_description": "Trilium за замовчуванням обмежує максимальну ширину вмісту, щоб поліпшити читабельність на широкоформатних екранах у режимі максимального розширення.", "default_description": "Trilium за замовчуванням обмежує максимальну ширину вмісту, щоб поліпшити читабельність на широкоформатних екранах у режимі максимального розширення.",
"max_width_label": "Максимальна ширина вмісту", "max_width_label": "Максимальна ширина вмісту",
"max_width_unit": "пікселів", "max_width_unit": "пікселів"
"apply_changes_description": "Щоб застосувати зміни ширини вмісту, натисніть на",
"reload_button": "перезавантажити інтерфейс",
"reload_description": "зміни в параметрах зовнішнього вигляду"
}, },
"native_title_bar": { "native_title_bar": {
"title": "Нативний рядок заголовка (потрібен перезапуск)", "title": "Нативний рядок заголовка (потрібен перезапуск)",

View File

@ -215,6 +215,30 @@ declare namespace Fancytree {
enableUpdate(enabled: boolean): void; enableUpdate(enabled: boolean): void;
} }
interface FancytreeNodeData {
noteId: string;
parentNoteId: string;
branchId: string;
isProtected: boolean;
noteType: NoteType;
}
interface FancytreeNewNode extends FancytreeNodeData {
title: string;
extraClasses: string;
icon: string;
refKey: string;
/** True if this node is loaded on demand, i.e. on first expansion. */
lazy: boolean;
/** Folder nodes have different default icons and click behavior. Note: Also non-folders may have children. */
folder: boolean;
/** Use isExpanded(), setExpanded() to access this property. */
expanded: boolean;
/** Node id (must be unique inside the tree) */
key: string;
children?: FancytreeNewNode[];
}
/** A FancytreeNode represents the hierarchical data model and operations. */ /** A FancytreeNode represents the hierarchical data model and operations. */
interface FancytreeNode { interface FancytreeNode {
// #region Properties // #region Properties
@ -227,7 +251,7 @@ declare namespace Fancytree {
/** Display name (may contain HTML) */ /** Display name (may contain HTML) */
title: string; title: string;
/** Contains all extra data that was passed on node creation */ /** Contains all extra data that was passed on node creation */
data: any; data: FancytreeNodeData;
/** Array of child nodes. For lazy nodes, null or undefined means 'not yet loaded'. Use an empty array to define a node that has no children. */ /** Array of child nodes. For lazy nodes, null or undefined means 'not yet loaded'. Use an empty array to define a node that has no children. */
children: FancytreeNode[]; children: FancytreeNode[];
/** Use isExpanded(), setExpanded() to access this property. */ /** Use isExpanded(), setExpanded() to access this property. */

View File

@ -23,6 +23,24 @@ export class CssVarReader {
return (!isNaN(number.valueOf()) ? number.valueOf() : defaultValue) return (!isNaN(number.valueOf()) ? number.valueOf() : defaultValue)
} }
asBoolean(defaultValue?: boolean) {
let value = this.value.toLocaleLowerCase().trim();
let result: boolean | undefined;
switch (value) {
case "true":
case "1":
result = true;
break;
case "false":
case "0":
result = false;
break;
}
return (result !== undefined) ? result : defaultValue;
}
asEnum<T>(enumType: T, defaultValue?: T[keyof T]): T[keyof T] | undefined { asEnum<T>(enumType: T, defaultValue?: T[keyof T]): T[keyof T] | undefined {
let result: T[keyof T] | undefined; let result: T[keyof T] | undefined;

View File

@ -6,7 +6,7 @@
.floating-buttons-children, .floating-buttons-children,
.show-floating-buttons { .show-floating-buttons {
position: absolute; position: absolute;
top: var(--floating-buttons-vert-offset, 10px); top: var(--floating-buttons-vert-offset, 14px);
inset-inline-end: var(--floating-buttons-horiz-offset, 10px); inset-inline-end: var(--floating-buttons-horiz-offset, 10px);
display: flex; display: flex;
flex-direction: row; flex-direction: row;

View File

@ -1,6 +1,6 @@
import { t } from "i18next"; import { t } from "i18next";
import "./FloatingButtons.css"; import "./FloatingButtons.css";
import { useNoteContext, useNoteLabel, useNoteLabelBoolean } from "./react/hooks"; import { useNoteContext, useNoteLabel, useNoteLabelBoolean, useTriliumEvent } from "./react/hooks";
import { useContext, useEffect, useMemo, useState } from "preact/hooks"; import { useContext, useEffect, useMemo, useState } from "preact/hooks";
import { ParentComponent } from "./react/react_utils"; import { ParentComponent } from "./react/react_utils";
import { EventData, EventNames } from "../components/app_context"; import { EventData, EventNames } from "../components/app_context";
@ -20,6 +20,7 @@ interface FloatingButtonsProps {
* properly handle rounded corners, as defined by the --border-radius CSS variable. * properly handle rounded corners, as defined by the --border-radius CSS variable.
*/ */
export default function FloatingButtons({ items }: FloatingButtonsProps) { export default function FloatingButtons({ items }: FloatingButtonsProps) {
const [ top, setTop ] = useState(0);
const { note, noteContext } = useNoteContext(); const { note, noteContext } = useNoteContext();
const parentComponent = useContext(ParentComponent); const parentComponent = useContext(ParentComponent);
const [ viewType ] = useNoteLabel(note, "viewType"); const [ viewType ] = useNoteLabel(note, "viewType");
@ -47,8 +48,14 @@ export default function FloatingButtons({ items }: FloatingButtonsProps) {
const [ visible, setVisible ] = useState(true); const [ visible, setVisible ] = useState(true);
useEffect(() => setVisible(true), [ note ]); useEffect(() => setVisible(true), [ note ]);
useTriliumEvent("contentSafeMarginChanged", (e) => {
if (e.noteContext === noteContext) {
setTop(e.top);
}
});
return ( return (
<div className="floating-buttons no-print"> <div className="floating-buttons no-print" style={{top}}>
<div className={`floating-buttons-children ${!visible ? "temporarily-hidden" : ""}`}> <div className={`floating-buttons-children ${!visible ? "temporarily-hidden" : ""}`}>
{context && items.map((Component) => ( {context && items.map((Component) => (
<Component {...context} /> <Component {...context} />

View File

@ -4,7 +4,7 @@ import Component from "../components/component";
import NoteContext from "../components/note_context"; import NoteContext from "../components/note_context";
import FNote from "../entities/fnote"; import FNote from "../entities/fnote";
import ActionButton, { ActionButtonProps } from "./react/ActionButton"; import ActionButton, { ActionButtonProps } from "./react/ActionButton";
import { useNoteLabelBoolean, useTriliumEvent, useTriliumOption, useWindowSize } from "./react/hooks"; import { useIsNoteReadOnly, useNoteLabelBoolean, useTriliumEvent, useTriliumOption, useWindowSize } from "./react/hooks";
import { useEffect, useLayoutEffect, useMemo, useRef, useState } from "preact/hooks"; import { useEffect, useLayoutEffect, useMemo, useRef, useState } from "preact/hooks";
import { createImageSrcUrl, openInAppHelpFromUrl } from "../services/utils"; import { createImageSrcUrl, openInAppHelpFromUrl } from "../services/utils";
import server from "../services/server"; import server from "../services/server";
@ -13,8 +13,6 @@ import toast from "../services/toast";
import { t } from "../services/i18n"; import { t } from "../services/i18n";
import { copyImageReferenceToClipboard } from "../services/image"; import { copyImageReferenceToClipboard } from "../services/image";
import tree from "../services/tree"; import tree from "../services/tree";
import protected_session_holder from "../services/protected_session_holder";
import options from "../services/options";
import { getHelpUrlForNote } from "../services/in_app_help"; import { getHelpUrlForNote } from "../services/in_app_help";
import froca from "../services/froca"; import froca from "../services/froca";
import NoteLink from "./react/NoteLink"; import NoteLink from "./react/NoteLink";
@ -101,48 +99,26 @@ function ToggleReadOnlyButton({ note, viewType, isDefaultViewMode }: FloatingBut
/> />
} }
function EditButton({ note, noteContext, isDefaultViewMode }: FloatingButtonContext) { function EditButton({ note, noteContext }: FloatingButtonContext) {
const [ animationClass, setAnimationClass ] = useState(""); const [animationClass, setAnimationClass] = useState("");
const [ isEnabled, setIsEnabled ] = useState(false); const {isReadOnly, enableEditing} = useIsNoteReadOnly(note, noteContext);
const isReadOnlyInfoBarDismissed = false; // TODO
useEffect(() => { useEffect(() => {
noteContext.isReadOnly().then(isReadOnly => { if (isReadOnly) {
setIsEnabled(
isDefaultViewMode
&& (!note.isProtected || protected_session_holder.isProtectedSessionAvailable())
&& !options.is("databaseReadonly")
&& isReadOnly
);
});
}, [ note ]);
useTriliumEvent("readOnlyTemporarilyDisabled", ({ noteContext: eventNoteContext }) => {
if (noteContext?.ntxId === eventNoteContext.ntxId) {
setIsEnabled(false);
}
});
// make the edit button stand out on the first display, otherwise
// it's difficult to notice that the note is readonly
useEffect(() => {
if (isEnabled) {
setAnimationClass("bx-tada bx-lg"); setAnimationClass("bx-tada bx-lg");
setTimeout(() => { setTimeout(() => {
setAnimationClass(""); setAnimationClass("");
}, 1700); }, 1700);
} }
}, [ isEnabled ]); }, [ isReadOnly ]);
return isEnabled && <FloatingButton return !!isReadOnly && isReadOnlyInfoBarDismissed && <FloatingButton
text={t("edit_button.edit_this_note")} text={t("edit_button.edit_this_note")}
icon="bx bx-pencil" icon="bx bx-pencil"
className={animationClass} className={animationClass}
onClick={() => { onClick={() => enableEditing()}
if (noteContext.viewScope) {
noteContext.viewScope.readOnlyTemporarilyDisabled = true;
appContext.triggerEvent("readOnlyTemporarilyDisabled", { noteContext });
}
}}
/> />
} }

View File

@ -1,9 +1,15 @@
.component.note-detail { .component.note-detail {
max-width: var(--max-content-width); /* Inherited from .note-split */
font-family: var(--detail-font-family); font-family: var(--detail-font-family);
font-size: var(--detail-font-size); font-size: var(--detail-font-size);
contain: none; contain: none;
} }
body.prefers-centered-content .note-detail {
/* Horizontally center the widget in its parent when the "Keep content centered" option is on */
margin-inline: auto;
}
.note-detail.full-height { .note-detail.full-height {
height: 100%; height: 100%;
} }

View File

@ -0,0 +1,19 @@
body.zen div.read-only-note-info-bar-widget {
width: fit-content;
max-width: var(--max-content-width);
border-radius: 8px;
border: unset;
margin: 0 auto;
}
.read-only-note-info-bar-widget-content {
display: flex;
justify-content: space-between;
align-items: center;
gap: 20px;
}
:root div.read-only-note-info-bar-widget button {
white-space: nowrap;
padding: 2px 8px;
}

View File

@ -0,0 +1,36 @@
import "./ReadOnlyNoteInfoBar.css";
import { t } from "../services/i18n";
import { useIsNoteReadOnly, useNoteContext, useTriliumEvent } from "./react/hooks"
import Button from "./react/Button";
import InfoBar from "./react/InfoBar";
export default function ReadOnlyNoteInfoBar(props: {}) {
const {note, noteContext} = useNoteContext();
const {isReadOnly, enableEditing} = useIsNoteReadOnly(note, noteContext);
const isExplicitReadOnly = note?.isLabelTruthy("readOnly");
return <InfoBar className="read-only-note-info-bar-widget"
type={(isExplicitReadOnly ? "subtle" : "prominent")}
style={{display: (!isReadOnly) ? "none" : undefined}}>
<div class="read-only-note-info-bar-widget-content">
{(isExplicitReadOnly) ? (
<div>{t("read-only-info.read-only-note")}</div>
) : (
<div>
{t("read-only-info.auto-read-only-note")}
&nbsp;
<a class="tn-link"
href="https://docs.triliumnotes.org/user-guide/concepts/notes/read-only-notes#automatic-read-only-mode">
{t("read-only-info.auto-read-only-learn-more")}
</a>
</div>
)}
<Button text={t("read-only-info.edit-note")}
icon="bx-pencil" onClick={() => enableEditing()} />
</div>
</InfoBar>
}

View File

@ -1,9 +1,16 @@
.note-list-widget { .note-list-widget {
min-height: 0; min-height: 0;
max-width: var(--max-content-width); /* Inherited from .note-split */
overflow: auto; overflow: auto;
contain: none !important; contain: none !important;
} }
body.prefers-centered-content .note-list-widget {
/* Horizontally center the widget in its parent when the "Keep content centered" option is on */
margin-inline: auto;
}
.note-list-widget .note-list { .note-list-widget .note-list {
padding: 10px; padding: 10px;
} }

View File

@ -0,0 +1,32 @@
import { it, describe, expect } from "vitest";
import { buildNote } from "../../../test/easy-froca";
import { getBoardData } from "./data";
import FBranch from "../../../entities/fbranch";
import froca from "../../../services/froca";
describe("Board data", () => {
it("deduplicates cloned notes", async () => {
const parentNote = buildNote({
title: "Board",
"#collection": "",
"#viewType": "board",
children: [
{ id: "note1", title: "First note", "#status": "To Do" },
{ id: "note2", title: "Second note", "#status": "In progress" },
{ id: "note3", title: "Third note", "#status": "Done" }
]
});
const branch = new FBranch(froca, {
branchId: "note1_note2",
notePosition: 10,
fromSearchNote: false,
noteId: "note2",
parentNoteId: "note1"
});
froca.branches["note1_note2"] = branch;
froca.getNoteFromCache("note1").addChild("note2", "note1_note2", false);
const data = await getBoardData(parentNote, "status", {}, false);
const noteIds = Array.from(data.byColumn.values()).flat().map(item => item.note.noteId);
expect(noteIds.length).toBe(3);
});
});

View File

@ -11,7 +11,7 @@ export async function getBoardData(parentNote: FNote, groupByColumn: string, per
const byColumn: ColumnMap = new Map(); const byColumn: ColumnMap = new Map();
// First, scan all notes to find what columns actually exist // First, scan all notes to find what columns actually exist
await recursiveGroupBy(parentNote.getChildBranches(), byColumn, groupByColumn, includeArchived); await recursiveGroupBy(parentNote.getChildBranches(), byColumn, groupByColumn, includeArchived, new Set<string>());
// Get all columns that exist in the notes // Get all columns that exist in the notes
const columnsFromNotes = [...byColumn.keys()]; const columnsFromNotes = [...byColumn.keys()];
@ -61,26 +61,28 @@ export async function getBoardData(parentNote: FNote, groupByColumn: string, per
}; };
} }
async function recursiveGroupBy(branches: FBranch[], byColumn: ColumnMap, groupByColumn: string, includeArchived: boolean) { async function recursiveGroupBy(branches: FBranch[], byColumn: ColumnMap, groupByColumn: string, includeArchived: boolean, seenNoteIds: Set<string>) {
for (const branch of branches) { for (const branch of branches) {
const note = await branch.getNote(); const note = await branch.getNote();
if (!note || (!includeArchived && note.isArchived)) continue; if (!note || (!includeArchived && note.isArchived)) continue;
if (note.type !== "search" && note.hasChildren()) { if (note.type !== "search" && note.hasChildren()) {
await recursiveGroupBy(note.getChildBranches(), byColumn, groupByColumn, includeArchived); await recursiveGroupBy(note.getChildBranches(), byColumn, groupByColumn, includeArchived, seenNoteIds);
} }
const group = note.getLabelValue(groupByColumn); const group = note.getLabelValue(groupByColumn);
if (!group) { if (!group || seenNoteIds.has(note.noteId)) {
continue; continue;
} }
if (!byColumn.has(group)) { if (!byColumn.has(group)) {
byColumn.set(group, []); byColumn.set(group, []);
} }
byColumn.get(group)!.push({ byColumn.get(group)!.push({
branch, branch,
note note
}); });
seenNoteIds.add(note.noteId);
} }
} }

View File

@ -197,11 +197,11 @@ function usePlugins(isEditable: boolean, isCalendarRoot: boolean) {
} }
function useLocale() { function useLocale() {
const [ locale ] = useTriliumOption("locale"); const [ formattingLocale ] = useTriliumOption("formattingLocale");
const [ calendarLocale, setCalendarLocale ] = useState<LocaleInput>(); const [ calendarLocale, setCalendarLocale ] = useState<LocaleInput>();
useEffect(() => { useEffect(() => {
const correspondingLocale = LOCALE_MAPPINGS[locale]; const correspondingLocale = LOCALE_MAPPINGS[formattingLocale];
if (correspondingLocale) { if (correspondingLocale) {
correspondingLocale().then((locale) => setCalendarLocale(locale.default)); correspondingLocale().then((locale) => setCalendarLocale(locale.default));
} else { } else {

View File

@ -0,0 +1,63 @@
import { EventData } from "../../components/app_context";
import BasicWidget from "../basic_widget";
import Container from "./container";
import NoteContext from "../../components/note_context";
export default class ContentHeader extends Container<BasicWidget> {
noteContext?: NoteContext;
thisElement?: HTMLElement;
parentElement?: HTMLElement;
resizeObserver: ResizeObserver;
currentHeight: number = 0;
currentSafeMargin: number = NaN;
constructor() {
super();
this.css("contain", "unset");
this.resizeObserver = new ResizeObserver(this.onResize.bind(this));
}
setNoteContextEvent({ noteContext }: EventData<"setNoteContext">) {
this.noteContext = noteContext;
this.init();
}
init() {
this.parentElement = this.parent!.$widget.get(0);
if (!this.parentElement) {
console.warn("No parent set for <ContentHeader>.");
return;
}
this.thisElement = this.$widget.get(0)!;
this.resizeObserver.observe(this.thisElement);
this.parentElement.addEventListener("scroll", this.updateSafeMargin.bind(this));
}
updateSafeMargin() {
const newSafeMargin = Math.max(this.currentHeight - this.parentElement!.scrollTop, 0);
if (newSafeMargin !== this.currentSafeMargin) {
this.currentSafeMargin = newSafeMargin;
this.triggerEvent("contentSafeMarginChanged", {
top: newSafeMargin,
noteContext: this.noteContext!
});
}
}
onResize(entries: ResizeObserverEntry[]) {
for (const entry of entries) {
if (entry.target === this.thisElement) {
this.currentHeight = entry.contentRect.height;
this.updateSafeMargin();
}
}
}
}

View File

@ -1,9 +1,10 @@
import { EventData } from "../../components/app_context.js"; import { EventData } from "../../components/app_context.js";
import { LOCALES } from "@triliumnext/commons";
import { readCssVar } from "../../utils/css-var.js";
import FlexContainer from "./flex_container.js"; import FlexContainer from "./flex_container.js";
import options from "../../services/options.js"; import options from "../../services/options.js";
import type BasicWidget from "../basic_widget.js"; import type BasicWidget from "../basic_widget.js";
import utils from "../../services/utils.js"; import utils from "../../services/utils.js";
import { LOCALES } from "@triliumnext/commons";
/** /**
* The root container is the top-most widget/container, from which the entire layout derives. * The root container is the top-most widget/container, from which the entire layout derives.
@ -30,9 +31,11 @@ export default class RootContainer extends FlexContainer<BasicWidget> {
window.visualViewport?.addEventListener("resize", () => this.#onMobileResize()); window.visualViewport?.addEventListener("resize", () => this.#onMobileResize());
} }
this.#setMotion(options.is("motionEnabled")); this.#setMaxContentWidth();
this.#setShadows(options.is("shadowsEnabled")); this.#setMotion();
this.#setBackdropEffects(options.is("backdropEffectsEnabled")); this.#setShadows();
this.#setBackdropEffects();
this.#setThemeCapabilities();
this.#setLocaleAndDirection(options.get("locale")); this.#setLocaleAndDirection(options.get("locale"));
return super.render(); return super.render();
@ -40,15 +43,21 @@ export default class RootContainer extends FlexContainer<BasicWidget> {
entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) { entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) {
if (loadResults.isOptionReloaded("motionEnabled")) { if (loadResults.isOptionReloaded("motionEnabled")) {
this.#setMotion(options.is("motionEnabled")); this.#setMotion();
} }
if (loadResults.isOptionReloaded("shadowsEnabled")) { if (loadResults.isOptionReloaded("shadowsEnabled")) {
this.#setShadows(options.is("shadowsEnabled")); this.#setShadows();
} }
if (loadResults.isOptionReloaded("backdropEffectsEnabled")) { if (loadResults.isOptionReloaded("backdropEffectsEnabled")) {
this.#setBackdropEffects(options.is("backdropEffectsEnabled")); this.#setBackdropEffects();
}
if (loadResults.isOptionReloaded("maxContentWidth")
|| loadResults.isOptionReloaded("centerContent")) {
this.#setMaxContentWidth();
} }
} }
@ -58,19 +67,38 @@ export default class RootContainer extends FlexContainer<BasicWidget> {
this.$widget.toggleClass("virtual-keyboard-opened", isKeyboardOpened); this.$widget.toggleClass("virtual-keyboard-opened", isKeyboardOpened);
} }
#setMotion(enabled: boolean) { #setMaxContentWidth() {
const width = Math.max(options.getInt("maxContentWidth") || 0, 640);
document.body.style.setProperty("--preferred-max-content-width", `${width}px`);
document.body.classList.toggle("prefers-centered-content", options.is("centerContent"));
}
#setMotion() {
const enabled = options.is("motionEnabled");
document.body.classList.toggle("motion-disabled", !enabled); document.body.classList.toggle("motion-disabled", !enabled);
jQuery.fx.off = !enabled; jQuery.fx.off = !enabled;
} }
#setShadows(enabled: boolean) { #setShadows() {
const enabled = options.is("shadowsEnabled");
document.body.classList.toggle("shadows-disabled", !enabled); document.body.classList.toggle("shadows-disabled", !enabled);
} }
#setBackdropEffects(enabled: boolean) { #setBackdropEffects() {
const enabled = options.is("backdropEffectsEnabled");
document.body.classList.toggle("backdrop-effects-disabled", !enabled); document.body.classList.toggle("backdrop-effects-disabled", !enabled);
} }
#setThemeCapabilities() {
// Supports background effects
const useBgfx = readCssVar(document.documentElement, "allow-background-effects")
.asBoolean(false);
document.body.classList.toggle("theme-supports-background-effects", useBgfx);
}
#setLocaleAndDirection(locale: string) { #setLocaleAndDirection(locale: string) {
const correspondingLocale = LOCALES.find(l => l.id === locale); const correspondingLocale = LOCALES.find(l => l.id === locale);
document.body.lang = locale; document.body.lang = locale;

View File

@ -56,6 +56,7 @@ const TPL = /*html*/`\
} }
</style> </style>
<div class="quick-edit-dialog-wrapper">
<div class="modal-dialog modal-lg" role="document"> <div class="modal-dialog modal-lg" role="document">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
@ -70,6 +71,7 @@ const TPL = /*html*/`\
</div> </div>
</div> </div>
</div> </div>
</div>
</div> </div>
`; `;
@ -78,6 +80,7 @@ export default class PopupEditorDialog extends Container<BasicWidget> {
private noteContext: NoteContext; private noteContext: NoteContext;
private $modalHeader!: JQuery<HTMLElement>; private $modalHeader!: JQuery<HTMLElement>;
private $modalBody!: JQuery<HTMLElement>; private $modalBody!: JQuery<HTMLElement>;
private $wrapper!: JQuery<HTMLDivElement>;
constructor() { constructor() {
super(); super();
@ -92,6 +95,7 @@ export default class PopupEditorDialog extends Container<BasicWidget> {
const $newWidget = $(TPL); const $newWidget = $(TPL);
this.$modalHeader = $newWidget.find(".modal-title"); this.$modalHeader = $newWidget.find(".modal-title");
this.$modalBody = $newWidget.find(".modal-body"); this.$modalBody = $newWidget.find(".modal-body");
this.$wrapper = $newWidget.find(".quick-edit-dialog-wrapper");
const children = this.$widget.children(); const children = this.$widget.children();
this.$modalHeader.append(children[0]); this.$modalHeader.append(children[0]);
@ -111,6 +115,21 @@ export default class PopupEditorDialog extends Container<BasicWidget> {
} }
}); });
const colorClass = this.noteContext.note?.getColorClass();
const wrapperElement = this.$wrapper.get(0)!;
if (colorClass) {
wrapperElement.className = "quick-edit-dialog-wrapper " + colorClass;
} else {
wrapperElement.className = "quick-edit-dialog-wrapper";
}
const customHue = getComputedStyle(wrapperElement).getPropertyValue("--custom-color-hue");
if (customHue) {
/* Apply the tinted-dialog class only if the custom color CSS class specifies a hue */
wrapperElement.classList.add("tinted-quick-edit-dialog");
}
const activeEl = document.activeElement; const activeEl = document.activeElement;
if (activeEl && "blur" in activeEl) { if (activeEl && "blur" in activeEl) {
(activeEl as HTMLElement).blur(); (activeEl as HTMLElement).blur();

View File

@ -173,14 +173,6 @@ interface ExpandedSubtreeResponse {
branchIds: string[]; branchIds: string[];
} }
interface Node extends Fancytree.NodeData {
noteId: string;
parentNoteId: string;
branchId: string;
isProtected: boolean;
noteType: NoteType;
}
interface RefreshContext { interface RefreshContext {
noteIdsToUpdate: Set<string>; noteIdsToUpdate: Set<string>;
noteIdsToReload: Set<string>; noteIdsToReload: Set<string>;
@ -769,7 +761,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
prepareChildren(parentNote: FNote) { prepareChildren(parentNote: FNote) {
utils.assertArguments(parentNote); utils.assertArguments(parentNote);
const noteList: Node[] = []; const noteList: Fancytree.FancytreeNewNode[] = [];
const hideArchivedNotes = this.hideArchivedNotes; const hideArchivedNotes = this.hideArchivedNotes;
@ -837,7 +829,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
const isFolder = note.isFolder(); const isFolder = note.isFolder();
const node: Node = { const node: Fancytree.FancytreeNewNode = {
noteId: note.noteId, noteId: note.noteId,
parentNoteId: branch.parentNoteId, parentNoteId: branch.parentNoteId,
branchId: branch.branchId, branchId: branch.branchId,
@ -849,7 +841,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
refKey: note.noteId, refKey: note.noteId,
lazy: true, lazy: true,
folder: isFolder, folder: isFolder,
expanded: branch.isExpanded && note.type !== "search", expanded: !!branch.isExpanded && note.type !== "search",
key: utils.randomString(12) // this should prevent some "duplicate key" errors key: utils.randomString(12) // this should prevent some "duplicate key" errors
}; };
@ -911,7 +903,6 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
return extraClasses.join(" "); return extraClasses.join(" ");
} }
/** @returns {FancytreeNode[]} */
getSelectedNodes(stopOnParents = false) { getSelectedNodes(stopOnParents = false) {
return this.tree.getSelectedNodes(stopOnParents); return this.tree.getSelectedNodes(stopOnParents);
} }
@ -1532,7 +1523,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
// Automatically expand the hoisted note by default // Automatically expand the hoisted note by default
const node = this.getActiveNode(); const node = this.getActiveNode();
if (node?.data.noteId === this.noteContext.hoistedNoteId){ if (node && node.data.noteId === this.noteContext.hoistedNoteId){
this.setExpanded(node.data.branchId, true); this.setExpanded(node.data.branchId, true);
} }
} }

View File

@ -52,6 +52,7 @@ export default class NoteWrapperWidget extends FlexContainer<BasicWidget> {
const note = this.noteContext?.note; const note = this.noteContext?.note;
if (!note) { if (!note) {
this.$widget.addClass("bgfx");
return; return;
} }
@ -61,7 +62,7 @@ export default class NoteWrapperWidget extends FlexContainer<BasicWidget> {
this.$widget.addClass(utils.getNoteTypeClass(note.type)); this.$widget.addClass(utils.getNoteTypeClass(note.type));
this.$widget.addClass(utils.getMimeTypeClass(note.mime)); this.$widget.addClass(utils.getMimeTypeClass(note.mime));
this.$widget.toggleClass(["bgfx", "options"], note.isOptions());
this.$widget.toggleClass("protected", note.isProtected); this.$widget.toggleClass("protected", note.isProtected);
const noteLanguage = note?.getLabelValue("language"); const noteLanguage = note?.getLabelValue("language");
@ -70,7 +71,7 @@ export default class NoteWrapperWidget extends FlexContainer<BasicWidget> {
} }
#isFullWidthNote(note: FNote) { #isFullWidthNote(note: FNote) {
if (["image", "mermaid", "book", "render", "canvas", "webView", "mindMap"].includes(note.type)) { if (["code", "image", "mermaid", "book", "render", "canvas", "webView", "mindMap"].includes(note.type)) {
return true; return true;
} }

View File

@ -0,0 +1,21 @@
.info-bar {
--link-color: var(--main-text-color);
margin-top: 4px;
contain: unset !important;
padding: 8px 20px;
color: var(--read-only-note-info-bar-color);
font-size: .9em;
}
.info-bar-prominent {
background: var(--alert-bar-background, var(--accented-background-color));
}
.info-bar-subtle {
color: var(--muted-text-color);
border-bottom: 1px solid var(--main-border-color);
margin-block: 0;
margin-inline: 10px;
padding-inline: 12px;
}

View File

@ -0,0 +1,19 @@
import "./InfoBar.css";
import { ComponentChildren, CSSProperties } from "preact";
export type InfoBarParams = {
type: "prominent" | "subtle",
className: string;
style: CSSProperties
children: ComponentChildren;
};
export default function InfoBar(props: InfoBarParams) {
return <div className={`info-bar ${props.className} info-bar-${props.type}`} style={props.style}>
{props?.children}
</div>
}
InfoBar.defaultProps = {
type: "prominent"
} as InfoBarParams

View File

@ -1,28 +1,28 @@
import { MutableRef, useCallback, useContext, useDebugValue, useEffect, useLayoutEffect, useMemo, useRef, useState } from "preact/hooks"; import { CSSProperties } from "preact/compat";
import appContext, { EventData, EventNames } from "../../components/app_context"; import { DragData } from "../note_tree";
import { ParentComponent, refToJQuerySelector } from "./react_utils";
import SpacedUpdate from "../../services/spaced_update";
import { FilterLabelsByType, KeyboardActionNames, OptionNames, RelationNames } from "@triliumnext/commons"; import { FilterLabelsByType, KeyboardActionNames, OptionNames, RelationNames } from "@triliumnext/commons";
import options, { type OptionValue } from "../../services/options"; import { Inputs, MutableRef, useCallback, useContext, useDebugValue, useEffect, useLayoutEffect, useMemo, useRef, useState } from "preact/hooks";
import utils, { escapeRegExp, reloadFrontendApp } from "../../services/utils"; import { ParentComponent, refToJQuerySelector } from "./react_utils";
import NoteContext from "../../components/note_context";
import BasicWidget, { ReactWrappedWidget } from "../basic_widget";
import FNote from "../../entities/fnote";
import attributes from "../../services/attributes";
import FBlob from "../../entities/fblob";
import NoteContextAwareWidget from "../note_context_aware_widget";
import { RefObject, VNode } from "preact"; import { RefObject, VNode } from "preact";
import { Tooltip } from "bootstrap"; import { Tooltip } from "bootstrap";
import { CSSProperties } from "preact/compat"; import { ViewMode, ViewScope } from "../../services/link";
import appContext, { CommandListenerData, EventData, EventNames } from "../../components/app_context";
import attributes from "../../services/attributes";
import BasicWidget, { ReactWrappedWidget } from "../basic_widget";
import Component from "../../components/component";
import FBlob from "../../entities/fblob";
import FNote from "../../entities/fnote";
import keyboard_actions from "../../services/keyboard_actions"; import keyboard_actions from "../../services/keyboard_actions";
import Mark from "mark.js"; import Mark from "mark.js";
import { DragData } from "../note_tree"; import NoteContext from "../../components/note_context";
import Component from "../../components/component"; import NoteContextAwareWidget from "../note_context_aware_widget";
import toast, { ToastOptions } from "../../services/toast"; import options, { type OptionValue } from "../../services/options";
import protected_session_holder from "../../services/protected_session_holder"; import protected_session_holder from "../../services/protected_session_holder";
import SpacedUpdate from "../../services/spaced_update";
import toast, { ToastOptions } from "../../services/toast";
import utils, { escapeRegExp, reloadFrontendApp } from "../../services/utils";
import server from "../../services/server"; import server from "../../services/server";
import { removeIndividualBinding } from "../../services/shortcuts"; import { removeIndividualBinding } from "../../services/shortcuts";
import { ViewScope } from "../../services/link";
export function useTriliumEvent<T extends EventNames>(eventName: T, handler: (data: EventData<T>) => void) { export function useTriliumEvent<T extends EventNames>(eventName: T, handler: (data: EventData<T>) => void) {
const parentComponent = useContext(ParentComponent); const parentComponent = useContext(ParentComponent);
@ -762,3 +762,51 @@ export function useKeyboardShortcuts(scope: "code-detail" | "text-detail", conta
} }
}, []); }, []);
} }
/**
* Indicates that the current note is in read-only mode, while an editing mode is available,
* and provides a way to switch to editing mode.
*/
export function useIsNoteReadOnly(note: FNote | null | undefined, noteContext: NoteContext | undefined) {
const [isReadOnly, setIsReadOnly] = useState<boolean | undefined>(undefined);
const enableEditing = useCallback(() => {
if (noteContext?.viewScope) {
noteContext.viewScope.readOnlyTemporarilyDisabled = true;
appContext.triggerEvent("readOnlyTemporarilyDisabled", {noteContext});
}
}, [noteContext]);
useEffect(() => {
if (note && noteContext) {
isNoteReadOnly(note, noteContext).then((readOnly) => {
setIsReadOnly(readOnly);
});
}
}, [note, noteContext]);
useTriliumEvent("readOnlyTemporarilyDisabled", ({noteContext: eventNoteContext}) => {
if (noteContext?.ntxId === eventNoteContext.ntxId) {
setIsReadOnly(false);
}
});
return {isReadOnly, enableEditing};
}
async function isNoteReadOnly(note: FNote, noteContext: NoteContext) {
if (note.isProtected && !protected_session_holder.isProtectedSessionAvailable()) {
return false;
}
if (options.is("databaseReadonly")) {
return false;
}
if (noteContext.viewScope?.viewMode !== "default" || !await noteContext.isReadOnly()) {
return false;
}
return true;
}

View File

@ -1,19 +1,20 @@
import { ConvertToAttachmentResponse } from "@triliumnext/commons"; import { ConvertToAttachmentResponse } from "@triliumnext/commons";
import appContext, { CommandNames } from "../../components/app_context";
import FNote from "../../entities/fnote"
import dialog from "../../services/dialog";
import { t } from "../../services/i18n"
import server from "../../services/server";
import toast from "../../services/toast";
import ws from "../../services/ws";
import ActionButton from "../react/ActionButton"
import Dropdown from "../react/Dropdown";
import { FormDropdownDivider, FormListItem } from "../react/FormList"; import { FormDropdownDivider, FormListItem } from "../react/FormList";
import { isElectron as getIsElectron, isMac as getIsMac } from "../../services/utils"; import { isElectron as getIsElectron, isMac as getIsMac } from "../../services/utils";
import { ParentComponent } from "../react/react_utils"; import { ParentComponent } from "../react/react_utils";
import { t } from "../../services/i18n"
import { useContext } from "preact/hooks"; import { useContext } from "preact/hooks";
import NoteContext from "../../components/note_context"; import { useIsNoteReadOnly } from "../react/hooks";
import ActionButton from "../react/ActionButton"
import appContext, { CommandNames } from "../../components/app_context";
import branches from "../../services/branches"; import branches from "../../services/branches";
import dialog from "../../services/dialog";
import Dropdown from "../react/Dropdown";
import FNote from "../../entities/fnote"
import NoteContext from "../../components/note_context";
import server from "../../services/server";
import toast from "../../services/toast";
import ws from "../../services/ws";
interface NoteActionsProps { interface NoteActionsProps {
note?: FNote; note?: FNote;
@ -52,6 +53,7 @@ function NoteContextMenu({ note, noteContext }: { note: FNote, noteContext?: Not
const isMac = getIsMac(); const isMac = getIsMac();
const hasSource = ["text", "code", "relationMap", "mermaid", "canvas", "mindMap", "aiChat"].includes(note.type); const hasSource = ["text", "code", "relationMap", "mermaid", "canvas", "mindMap", "aiChat"].includes(note.type);
const isSearchOrBook = ["search", "book"].includes(note.type); const isSearchOrBook = ["search", "book"].includes(note.type);
const {isReadOnly, enableEditing} = useIsNoteReadOnly(note, noteContext);
return ( return (
<Dropdown <Dropdown
@ -59,8 +61,14 @@ function NoteContextMenu({ note, noteContext }: { note: FNote, noteContext?: Not
className="note-actions" className="note-actions"
hideToggleArrow hideToggleArrow
noSelectButtonStyle noSelectButtonStyle
iconAction iconAction>
>
{isReadOnly && <>
<CommandItem icon="bx bx-pencil" text={t("read-only-info.edit-note")}
command={() => enableEditing()} />
<FormDropdownDivider />
</>}
{canBeConvertedToAttachment && <ConvertToAttachment note={note} /> } {canBeConvertedToAttachment && <ConvertToAttachment note={note} /> }
{note.type === "render" && <CommandItem command="renderActiveNote" icon="bx bx-extension" text={t("note_actions.re_render_note")} />} {note.type === "render" && <CommandItem command="renderActiveNote" icon="bx bx-extension" text={t("note_actions.re_render_note")} />}
<CommandItem command="findInText" icon="bx bx-search" disabled={!isSearchable} text={t("note_actions.search_in_note")} /> <CommandItem command="findInText" icon="bx bx-search" disabled={!isSearchable} text={t("note_actions.search_in_note")} />

View File

@ -0,0 +1,7 @@
.shared-info-widget {
display: flex;
}
.shared-info-widget button {
margin-inline-start: 8px;
}

View File

@ -1,11 +1,12 @@
import { useEffect, useState } from "preact/hooks"; import "./shared_info.css";
import { t } from "../services/i18n"; import { t } from "../services/i18n";
import Alert from "./react/Alert"; import { useEffect, useState } from "preact/hooks";
import { useNoteContext, useTriliumEvent, useTriliumOption } from "./react/hooks"; import { useNoteContext, useTriliumEvent, useTriliumOption } from "./react/hooks";
import FNote from "../entities/fnote";
import attributes from "../services/attributes"; import attributes from "../services/attributes";
import RawHtml from "./react/RawHtml"; import FNote from "../entities/fnote";
import HelpButton from "./react/HelpButton"; import HelpButton from "./react/HelpButton";
import InfoBar from "./react/InfoBar";
import RawHtml from "./react/RawHtml";
export default function SharedInfo() { export default function SharedInfo() {
const { note } = useNoteContext(); const { note } = useNoteContext();
@ -35,7 +36,7 @@ export default function SharedInfo() {
link = `${location.protocol}//${host}${location.pathname}share/${shareId}`; link = `${location.protocol}//${host}${location.pathname}share/${shareId}`;
} }
setLink(`<a href="${link}" class="external">${link}</a>`); setLink(`<a href="${link}" class="external tn-link">${link}</a>`);
} }
useEffect(refresh, [ note ]); useEffect(refresh, [ note ]);
@ -48,20 +49,14 @@ export default function SharedInfo() {
}); });
return ( return (
<Alert className="shared-info-widget" type="warning" style={{ <InfoBar className="shared-info-widget" type="subtle" style={{display: (!link) ? "none" : undefined}}>
contain: "none",
margin: "10px",
padding: "10px",
fontWeight: "bold",
display: !link ? "none" : undefined
}}>
{link && ( {link && (
<RawHtml html={syncServerHost <RawHtml html={syncServerHost
? t("shared_info.shared_publicly", { link }) ? t("shared_info.shared_publicly", { link })
: t("shared_info.shared_locally", { link })} /> : t("shared_info.shared_locally", { link })} />
)} )}
<HelpButton helpPage="R9pX4DGra2Vt" style={{ width: "24px", height: "24px" }} /> <HelpButton helpPage="R9pX4DGra2Vt" style={{ width: "24px", height: "24px" }} />
</Alert> </InfoBar>
) )
} }

View File

@ -284,7 +284,8 @@ function SmoothScrollEnabledOption() {
} }
function MaxContentWidth() { function MaxContentWidth() {
const [ maxContentWidth, setMaxContentWidth ] = useTriliumOption("maxContentWidth"); const [maxContentWidth, setMaxContentWidth] = useTriliumOption("maxContentWidth");
const [centerContent, setCenterContent] = useTriliumOptionBool("centerContent");
return ( return (
<OptionsSection title={t("max_content_width.title")}> <OptionsSection title={t("max_content_width.title")}>
@ -300,9 +301,9 @@ function MaxContentWidth() {
</FormGroup> </FormGroup>
</Column> </Column>
<p> <FormCheckbox label={t("max_content_width.centerContent")}
{t("max_content_width.apply_changes_description")} <Button text={t("max_content_width.reload_button")} size="micro" onClick={reloadFrontendApp} /> currentValue={centerContent}
</p> onChange={setCenterContent} />
</OptionsSection> </OptionsSection>
) )
} }

View File

@ -97,7 +97,7 @@ function TokenList({ tokens }: { tokens: EtapiToken[] }) {
return ( return (
tokens.length ? ( tokens.length ? (
<div style={{ overflow: "auto", height: "500px"}}> <div style={{ overflow: "auto"}}>
<table className="table table-stripped"> <table className="table table-stripped">
<thead> <thead>
<tr> <tr>

View File

@ -35,7 +35,7 @@
"@triliumnext/commons": "workspace:*", "@triliumnext/commons": "workspace:*",
"@triliumnext/server": "workspace:*", "@triliumnext/server": "workspace:*",
"copy-webpack-plugin": "13.0.1", "copy-webpack-plugin": "13.0.1",
"electron": "38.5.0", "electron": "38.6.0",
"@electron-forge/cli": "7.10.2", "@electron-forge/cli": "7.10.2",
"@electron-forge/maker-deb": "7.10.2", "@electron-forge/maker-deb": "7.10.2",
"@electron-forge/maker-dmg": "7.10.2", "@electron-forge/maker-dmg": "7.10.2",

View File

@ -12,7 +12,7 @@
"@triliumnext/desktop": "workspace:*", "@triliumnext/desktop": "workspace:*",
"@types/fs-extra": "11.0.4", "@types/fs-extra": "11.0.4",
"copy-webpack-plugin": "13.0.1", "copy-webpack-plugin": "13.0.1",
"electron": "38.5.0", "electron": "38.6.0",
"fs-extra": "11.3.2" "fs-extra": "11.3.2"
}, },
"scripts": { "scripts": {

View File

@ -81,7 +81,7 @@
"debounce": "3.0.0", "debounce": "3.0.0",
"debug": "4.4.3", "debug": "4.4.3",
"ejs": "3.1.10", "ejs": "3.1.10",
"electron": "38.5.0", "electron": "38.6.0",
"electron-debug": "4.1.0", "electron-debug": "4.1.0",
"electron-window-state": "5.0.3", "electron-window-state": "5.0.3",
"escape-html": "1.0.3", "escape-html": "1.0.3",
@ -97,7 +97,7 @@
"html2plaintext": "2.1.4", "html2plaintext": "2.1.4",
"http-proxy-agent": "7.0.2", "http-proxy-agent": "7.0.2",
"https-proxy-agent": "7.0.6", "https-proxy-agent": "7.0.6",
"i18next": "25.6.0", "i18next": "25.6.1",
"i18next-fs-backend": "2.6.0", "i18next-fs-backend": "2.6.0",
"image-type": "6.0.0", "image-type": "6.0.0",
"ini": "6.0.0", "ini": "6.0.0",
@ -105,7 +105,7 @@
"is-svg": "6.1.0", "is-svg": "6.1.0",
"jimp": "1.6.0", "jimp": "1.6.0",
"js-yaml": "4.1.0", "js-yaml": "4.1.0",
"marked": "16.4.1", "marked": "16.4.2",
"mime-types": "3.0.1", "mime-types": "3.0.1",
"multer": "2.0.2", "multer": "2.0.2",
"normalize-strings": "1.1.1", "normalize-strings": "1.1.1",
@ -126,7 +126,7 @@
"tmp": "0.2.5", "tmp": "0.2.5",
"turndown": "7.2.2", "turndown": "7.2.2",
"unescape": "1.0.1", "unescape": "1.0.1",
"vite": "7.2.1", "vite": "7.2.2",
"ws": "8.18.3", "ws": "8.18.3",
"xml2js": "0.6.2", "xml2js": "0.6.2",
"yauzl": "3.2.0" "yauzl": "3.2.0"

View File

@ -4,7 +4,6 @@
<figcaption>Screenshot of the note contextual menu indicating the “Export as PDF” <figcaption>Screenshot of the note contextual menu indicating the “Export as PDF”
option.</figcaption> option.</figcaption>
</figure> </figure>
<h2>Printing</h2> <h2>Printing</h2>
<p>This feature allows printing of notes. It works on both the desktop client, <p>This feature allows printing of notes. It works on both the desktop client,
but also on the web.</p> but also on the web.</p>
@ -60,9 +59,9 @@ class="admonition note">
orientation, size. However, there are a few&nbsp;<a class="reference-link" orientation, size. However, there are a few&nbsp;<a class="reference-link"
href="#root/_help_zEY4DaJG4YT5">Attributes</a>&nbsp;to adjust some of the settings:</p> href="#root/_help_zEY4DaJG4YT5">Attributes</a>&nbsp;to adjust some of the settings:</p>
<ul> <ul>
<li>To print in landscape mode instead of portrait (useful for big diagrams <li data-list-item-id="e059818dc4b086a895efa23fdde670cb0">To print in landscape mode instead of portrait (useful for big diagrams
or slides), add <code>#printLandscape</code>.</li> or slides), add <code>#printLandscape</code>.</li>
<li>By default, the resulting PDF will be in Letter format. It is possible <li data-list-item-id="ebb801d5830e9662602ce85e96e351ee5">By default, the resulting PDF will be in Letter format. It is possible
to adjust it to another page size via the <code>#printPageSize</code> attribute, to adjust it to another page size via the <code>#printPageSize</code> attribute,
with one of the following values: <code>A0</code>, <code>A1</code>, <code>A2</code>, <code>A3</code>, <code>A4</code>, <code>A5</code>, <code>A6</code>, <code>Legal</code>, <code>Letter</code>, <code>Tabloid</code>, <code>Ledger</code>.</li> with one of the following values: <code>A0</code>, <code>A1</code>, <code>A2</code>, <code>A3</code>, <code>A4</code>, <code>A5</code>, <code>A6</code>, <code>Legal</code>, <code>Letter</code>, <code>Tabloid</code>, <code>Ledger</code>.</li>
</ul> </ul>
@ -76,9 +75,9 @@ class="admonition note">
href="#root/_help_4TIF1oA4VQRO">Options</a>&nbsp;and assigning a key combination href="#root/_help_4TIF1oA4VQRO">Options</a>&nbsp;and assigning a key combination
for:</p> for:</p>
<ul> <ul>
<li><em>Print Active Note</em> <li class="ck-list-marker-italic" data-list-item-id="ed834da40ebe17dd104c66956579e8db8"><em>Print Active Note</em>
</li> </li>
<li><em>Export Active Note as PDF</em> <li class="ck-list-marker-italic" data-list-item-id="e12469c162de60af8653a92238f286176"><em>Export Active Note as PDF</em>
</li> </li>
</ul> </ul>
<h2>Constraints &amp; limitations</h2> <h2>Constraints &amp; limitations</h2>
@ -86,27 +85,58 @@ class="admonition note">
supported when printing, in which case the <em>Print</em> and <em>Export as PDF</em> options supported when printing, in which case the <em>Print</em> and <em>Export as PDF</em> options
will be disabled.</p> will be disabled.</p>
<ul> <ul>
<li>For&nbsp;<a class="reference-link" href="#root/_help_6f9hih2hXXZk">Code</a>&nbsp;notes: <li data-list-item-id="ecbc8f07fc543357dbe65e874d2812923">For&nbsp;<a class="reference-link" href="#root/_help_6f9hih2hXXZk">Code</a>&nbsp;notes:
<ul> <ul>
<li>Line numbers are not printed.</li> <li data-list-item-id="e5a65e990187f7457b1ef3b90b3efca65">Line numbers are not printed.</li>
<li>Syntax highlighting is enabled, however a default theme (Visual Studio) <li data-list-item-id="ed32da7175b6215d5c1461029b85310b6">Syntax highlighting is enabled, however a default theme (Visual Studio)
is enforced.</li> is enforced.</li>
</ul> </ul>
</li> </li>
<li>For&nbsp;<a class="reference-link" href="#root/_help_GTwFsgaA0lCt">Collections</a>: <li data-list-item-id="e2336e670a5137a961dbaa520180f1ca3">For&nbsp;<a class="reference-link" href="#root/_help_GTwFsgaA0lCt">Collections</a>:
<ul> <ul>
<li>Only&nbsp;<a class="reference-link" href="#root/_help_zP3PMqaG71Ct">Presentation View</a>&nbsp;is <li data-list-item-id="e2dfe21a479e4e4574d70e3c818d3580c">Only&nbsp;<a class="reference-link" href="#root/_help_zP3PMqaG71Ct">Presentation</a>&nbsp;is
currently supported.</li> currently supported.</li>
<li>We plan to add support for all the collection types at some point.</li> <li data-list-item-id="eb710e8646deac11a960fc762ff059ffc">We plan to add support for all the collection types at some point.</li>
</ul> </ul>
</li> </li>
<li>Using&nbsp;<a class="reference-link" href="#root/_help_AlhDUqhENtH7">Custom app-wide CSS</a>&nbsp;for <li data-list-item-id="e92e4035db060328f92b290f201746687">Using&nbsp;<a class="reference-link" href="#root/_help_AlhDUqhENtH7">Custom app-wide CSS</a>&nbsp;for
printing is not longer supported, due to a more stable but isolated mechanism. printing is not longer supported, due to a more stable but isolated mechanism.
<ul> <ul>
<li>We plan to introduce a new mechanism specifically for a print CSS.</li> <li data-list-item-id="e8ceb3650a468052a8728a40f05ba8ba9">We plan to introduce a new mechanism specifically for a print CSS.</li>
</ul> </ul>
</li> </li>
</ul> </ul>
<h2>Customizing the print CSS</h2>
<p>As an advanced use case, it's possible to customize the CSS used for printing
such as adjusting the fonts, sizes or margins. Note that&nbsp;<a class="reference-link"
href="#root/pOsGYCXsbNQG/pKK96zzmvBGf/_help_AlhDUqhENtH7">Custom app-wide CSS</a>&nbsp;will
not work for printing.</p>
<p>To do so:</p>
<ul>
<li data-list-item-id="e9888834b45670c7ab11c0f229e38e32f">Create a CSS <a href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_6f9hih2hXXZk">code note</a>.</li>
<li
data-list-item-id="ea9e3983ea0c81ecc73c6cd73bcb3e400">On the note being printed, apply the <code>~printCss</code> relation to
point to the newly created CSS code note.</li>
<li data-list-item-id="ed4fdf9dd70c9770c03637eb4fb011654">To apply the CSS to multiple notes, consider using <a href="#root/pOsGYCXsbNQG/tC7s2alapj8V/zEY4DaJG4YT5/_help_bwZpz2ajCEwO">inheritable attributes</a> or&nbsp;
<a
class="reference-link" href="#root/pOsGYCXsbNQG/tC7s2alapj8V/_help_KC1HB96bqqHX">Templates</a>.</li>
</ul>
<p>For example, to change the font of the document from the one defined by
the theme or the user to a serif one:</p><pre><code class="language-text-x-trilium-auto">body {
--main-font-family: serif !important;
--detail-font-family: var(--main-font-family) !important;
}</code></pre>
<p>To remark:</p>
<ul>
<li data-list-item-id="e0fcaa62313f3f428f8243c0631a578b3">Multiple CSS notes can be add by using multiple <code>~printCss</code> relations.</li>
<li
data-list-item-id="e0388e16113a44b8200aed433f680b795">If the note pointing to the <code>printCss</code> doesn't have the right
note type or mime type, it will be ignored.</li>
<li data-list-item-id="ec4c3f5dcee6428c4a5e409f1461c2433">If migrating from a previous version where&nbsp;<a class="reference-link"
href="#root/pOsGYCXsbNQG/pKK96zzmvBGf/_help_AlhDUqhENtH7">Custom app-wide CSS</a>,
there's no need for <code>@media print {</code> since the style-sheet is
used only for printing.</li>
</ul>
<h2>Under the hood</h2> <h2>Under the hood</h2>
<p>Both printing and exporting as PDF use the same mechanism: a note is rendered <p>Both printing and exporting as PDF use the same mechanism: a note is rendered
individually in a separate webpage that is then sent to the browser or individually in a separate webpage that is then sent to the browser or

View File

@ -1,10 +1,11 @@
<p>It is possible to provide a CSS file to be used regardless of the theme <p>It is possible to provide a CSS file to be used regardless of the theme
set by the user.</p> set by the user.</p>
<table> <figure class="table">
<table>
<thead> <thead>
<tr> <tr>
<th></th> <th>&nbsp;</th>
<th></th> <th>&nbsp;</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -24,38 +25,37 @@
<td> <td>
<img src="3_Custom app-wide CSS_image.png"> <img src="3_Custom app-wide CSS_image.png">
</td> </td>
<td>Type the desired CSS.&nbsp;&nbsp; <td>Type the desired CSS.&nbsp;&nbsp;&nbsp;
<br> <br>
<br>Generally it's a good idea to append <code>!important</code> for the styles <br>Generally it's a good idea to append <code>!important</code> for the styles
that are being changed, in order to prevent other</td> that are being changed, in order to prevent other</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</figure>
<h2>Seeing the changes</h2> <h2>Seeing the changes</h2>
<p>Adding a new <em>app CSS note</em> or modifying an existing one does not <p>Adding a new <em>app CSS note</em> or modifying an existing one does not
immediately apply changes. To see the changes, press Ctrl+Shift+R to refresh immediately apply changes. To see the changes, press Ctrl+Shift+R to refresh
the page first.</p> the page first.</p>
<h2>Sample use cases</h2> <h2>Sample use cases</h2>
<h3>Customizing the printing stylesheet</h3> <h3>Customizing the printing stylesheet</h3>
<p>When printing a document or exporting as PDF, it is possible to adjust <aside class="admonition tip">
the style by creating a CSS note that uses the <code>@media</code>selector.</p> <p>Since v0.99.2, it's no longer possible to use <code>#appCss</code> to customize
<p>For example, to change the font of the document from the one defined by the printing CSS, since the printing is now done in an isolated environment.</p>
the theme or the user to a serif one:</p><pre><code class="language-text-x-trilium-auto">@media print { <p>However, it's still possible to customize the CSS via <code>~printCss</code>;
body { see&nbsp;<a class="reference-link" href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/BFs8mudNFgCS/_help_NRnIZmSMc5sj">Printing &amp; Exporting as PDF</a>&nbsp;for
--main-font-family: serif !important; more information.</p>
--detail-font-family: var(--main-font-family) !important; </aside>
}
}</code></pre>
<h3>Per-workspace styles</h3> <h3>Per-workspace styles</h3>
<p>When using&nbsp;<a class="reference-link" href="#root/_help_9sRHySam5fXb">Workspaces</a>, <p>When using&nbsp;<a class="reference-link" href="#root/_help_9sRHySam5fXb">Workspaces</a>,
it can be helpful to create a visual distinction between notes in different it can be helpful to create a visual distinction between notes in different
workspaces.</p> workspaces.</p>
<p>To do so:</p> <p>To do so:</p>
<ol> <ol>
<li>In the note with <code>#workspace</code>, add an inheritable attribute <code>#cssClass(inheritable)</code> with <li data-list-item-id="e591e9a3631fa3729bc62dbfc7c30cf73">In the note with <code>#workspace</code>, add an inheritable attribute <code>#cssClass(inheritable)</code> with
a value that uniquely identifies the workspace (say <code>my-workspace</code>).</li> a value that uniquely identifies the workspace (say <code>my-workspace</code>).</li>
<li>Anywhere in the note structure, create a CSS note with <code>#appCss</code>.</li> <li
data-list-item-id="eb0073ce6acba5e4f91cc4bfc2acbdd2a">Anywhere in the note structure, create a CSS note with <code>#appCss</code>.</li>
</ol> </ol>
<h4>Change the color of the icons in the&nbsp;<a class="reference-link" href="#root/_help_oPVyFC7WL2Lp">Note Tree</a></h4><pre><code class="language-text-x-trilium-auto">.fancytree-node.my-workspace.fancytree-custom-icon { <h4>Change the color of the icons in the&nbsp;<a class="reference-link" href="#root/_help_oPVyFC7WL2Lp">Note Tree</a></h4><pre><code class="language-text-x-trilium-auto">.fancytree-node.my-workspace.fancytree-custom-icon {
color: #ff0000; color: #ff0000;
@ -71,8 +71,8 @@
width="641" height="630"> width="641" height="630">
</figure> </figure>
<ol> <ol>
<li>Insert an image in any note and take the URL of the image.</li> <li data-list-item-id="e3297614b2f73893bb02f38ab1c3a4307">Insert an image in any note and take the URL of the image.</li>
<li>Use the following CSS, adjusting the <code>background-image</code> and <code>width</code> and <code>height</code> to <li data-list-item-id="eaedddcc05035bff463d91c83484faac2">Use the following CSS, adjusting the <code>background-image</code> and <code>width</code> and <code>height</code> to
the desired values.</li> the desired values.</li>
</ol><pre><code class="language-text-x-trilium-auto">.note-split.my-workspace .scrolling-container:after { </ol><pre><code class="language-text-x-trilium-auto">.note-split.my-workspace .scrolling-container:after {
position: fixed; position: fixed;
@ -92,5 +92,5 @@
<p>Some parts of the application can't be styled directly via custom CSS <p>Some parts of the application can't be styled directly via custom CSS
because they are rendered in an isolated mode (shadow DOM), more specifically:</p> because they are rendered in an isolated mode (shadow DOM), more specifically:</p>
<ul> <ul>
<li>The slides in a&nbsp;<a class="reference-link" href="#root/_help_zP3PMqaG71Ct">Presentation View</a>.</li> <li data-list-item-id="ed33bb330d4e5c6d1219334b51edcc1b7">The slides in a&nbsp;<a class="reference-link" href="#root/_help_zP3PMqaG71Ct">Presentation</a>.</li>
</ul> </ul>

View File

@ -331,6 +331,8 @@
"calendar-title": "Calendar", "calendar-title": "Calendar",
"recent-changes-title": "Recent Changes", "recent-changes-title": "Recent Changes",
"bookmarks-title": "Bookmarks", "bookmarks-title": "Bookmarks",
"command-palette": "Open Command Palette",
"zen-mode": "Zen Mode",
"open-today-journal-note-title": "Open Today's Journal Note", "open-today-journal-note-title": "Open Today's Journal Note",
"quick-search-title": "Quick Search", "quick-search-title": "Quick Search",
"protected-session-title": "Protected Session", "protected-session-title": "Protected Session",

View File

@ -28,12 +28,6 @@
<%- include("./partials/windowGlobal.ejs", locals) %> <%- include("./partials/windowGlobal.ejs", locals) %>
<style>
.note-split {
max-width: <%= maxContentWidth %>px;
}
</style>
<!-- Required for match the PWA's top bar color with the theme --> <!-- Required for match the PWA's top bar color with the theme -->
<!-- This works even when the user directly changes --root-background in CSS --> <!-- This works even when the user directly changes --root-background in CSS -->
<div id="background-color-tracker" style="position: absolute; visibility: hidden; color: var(--root-background); transition: color 1ms;"></div> <div id="background-color-tracker" style="position: absolute; visibility: hidden; color: var(--root-background); transition: color 1ms;"></div>

View File

@ -68,6 +68,7 @@ const ALLOWED_OPTIONS = new Set<OptionNames>([
"smoothScrollEnabled", "smoothScrollEnabled",
"backdropEffectsEnabled", "backdropEffectsEnabled",
"maxContentWidth", "maxContentWidth",
"centerContent",
"compressImages", "compressImages",
"downloadImagesAutomatically", "downloadImagesAutomatically",
"minTocHeadings", "minTocHeadings",

View File

@ -57,7 +57,6 @@ function index(req: Request, res: Response) {
isDev, isDev,
isMainWindow: view === "mobile" ? true : !req.query.extraWindow, isMainWindow: view === "mobile" ? true : !req.query.extraWindow,
isProtectedSessionAvailable: protectedSessionService.isProtectedSessionAvailable(), isProtectedSessionAvailable: protectedSessionService.isProtectedSessionAvailable(),
maxContentWidth: Math.max(640, parseInt(options.maxContentWidth)),
triliumVersion: packageJson.version, triliumVersion: packageJson.version,
assetPath, assetPath,
appPath, appPath,

View File

@ -44,13 +44,42 @@ export default function buildLaunchBarConfig() {
}; };
const desktopAvailableLaunchers: HiddenSubtreeItem[] = [ const desktopAvailableLaunchers: HiddenSubtreeItem[] = [
{ id: "_lbBackInHistory", ...sharedLaunchers.backInHistory }, {
{ id: "_lbForwardInHistory", ...sharedLaunchers.forwardInHistory }, id: "_lbBackInHistory",
{ id: "_lbBackendLog", title: t("hidden-subtree.backend-log-title"), type: "launcher", targetNoteId: "_backendLog", icon: "bx bx-terminal" }, ...sharedLaunchers.backInHistory
},
{
id: "_lbForwardInHistory",
...sharedLaunchers.forwardInHistory
},
{
id: "_commandPalette",
title: t("hidden-subtree.command-palette"),
type: "launcher",
command: "commandPalette",
icon: "bx bx-chevron-right-square"
},
{
id: "_lbBackendLog",
title: t("hidden-subtree.backend-log-title"),
type: "launcher",
targetNoteId: "_backendLog",
icon: "bx bx-detail"
},
{
id: "_zenMode",
title: t("hidden-subtree.zen-mode"),
type: "launcher",
command: "toggleZenMode",
icon: "bx bxs-yin-yang"
}
]; ];
const desktopVisibleLaunchers: HiddenSubtreeItem[] = [ const desktopVisibleLaunchers: HiddenSubtreeItem[] = [
{ id: "_lbNewNote", ...sharedLaunchers.newNote }, {
id: "_lbNewNote",
...sharedLaunchers.newNote
},
{ {
id: "_lbSearch", id: "_lbSearch",
title: t("hidden-subtree.search-notes-title"), title: t("hidden-subtree.search-notes-title"),
@ -67,7 +96,12 @@ export default function buildLaunchBarConfig() {
icon: "bx bx-send", icon: "bx bx-send",
attributes: [{ type: "label", name: "desktopOnly" }] attributes: [{ type: "label", name: "desktopOnly" }]
}, },
{ id: "_lbNoteMap", title: t("hidden-subtree.note-map-title"), type: "launcher", targetNoteId: "_globalNoteMap", icon: "bx bxs-network-chart" }, { id: "_lbNoteMap",
title: t("hidden-subtree.note-map-title"),
type: "launcher",
targetNoteId: "_globalNoteMap",
icon: "bx bxs-network-chart"
},
{ {
id: "_lbLlmChat", id: "_lbLlmChat",
title: t("hidden-subtree.llm-chat-title"), title: t("hidden-subtree.llm-chat-title"),
@ -78,12 +112,41 @@ export default function buildLaunchBarConfig() {
{ type: "label", name: "desktopOnly" } { type: "label", name: "desktopOnly" }
] ]
}, },
{ id: "_lbCalendar", ...sharedLaunchers.calendar }, {
{ id: "_lbRecentChanges", ...sharedLaunchers.recentChanges }, id: "_lbCalendar",
{ id: "_lbSpacer1", title: t("hidden-subtree.spacer-title"), type: "launcher", builtinWidget: "spacer", baseSize: "50", growthFactor: "0" }, ...sharedLaunchers.calendar
{ id: "_lbBookmarks", title: t("hidden-subtree.bookmarks-title"), type: "launcher", builtinWidget: "bookmarks", icon: "bx bx-bookmark" }, },
{ id: "_lbToday", ...sharedLaunchers.openToday }, {
{ id: "_lbSpacer2", title: t("hidden-subtree.spacer-title"), type: "launcher", builtinWidget: "spacer", baseSize: "0", growthFactor: "1" }, id: "_lbRecentChanges",
...sharedLaunchers.recentChanges
},
{
id: "_lbSpacer1",
title: t("hidden-subtree.spacer-title"),
type: "launcher",
builtinWidget: "spacer",
baseSize: "50",
growthFactor: "0"
},
{
id: "_lbBookmarks",
title: t("hidden-subtree.bookmarks-title"),
type: "launcher",
builtinWidget: "bookmarks",
icon: "bx bx-bookmark"
},
{
id: "_lbToday",
...sharedLaunchers.openToday
},
{
id: "_lbSpacer2",
title: t("hidden-subtree.spacer-title"),
type: "launcher",
builtinWidget: "spacer",
baseSize: "0",
growthFactor: "1"
},
{ {
id: "_lbQuickSearch", id: "_lbQuickSearch",
title: t("hidden-subtree.quick-search-title"), title: t("hidden-subtree.quick-search-title"),
@ -92,9 +155,26 @@ export default function buildLaunchBarConfig() {
icon: "bx bx-rectangle", icon: "bx bx-rectangle",
attributes: [{ type: "label", name: "docName", value: "launchbar_quick_search" }] attributes: [{ type: "label", name: "docName", value: "launchbar_quick_search" }]
}, },
{ id: "_lbProtectedSession", title: t("hidden-subtree.protected-session-title"), type: "launcher", builtinWidget: "protectedSession", icon: "bx bx bx-shield-quarter" }, {
{ id: "_lbSyncStatus", title: t("hidden-subtree.sync-status-title"), type: "launcher", builtinWidget: "syncStatus", icon: "bx bx-wifi" }, id: "_lbProtectedSession",
{ id: "_lbSettings", title: t("hidden-subtree.settings-title"), type: "launcher", command: "showOptions", icon: "bx bx-cog" } title: t("hidden-subtree.protected-session-title"),
type: "launcher", builtinWidget: "protectedSession",
icon: "bx bx bx-shield-quarter"
},
{
id: "_lbSyncStatus",
title: t("hidden-subtree.sync-status-title"),
type: "launcher",
builtinWidget: "syncStatus",
icon: "bx bx-wifi"
},
{
id: "_lbSettings",
title: t("hidden-subtree.settings-title"),
type: "launcher",
command: "showOptions",
icon: "bx bx-cog"
}
]; ];
const mobileAvailableLaunchers: HiddenSubtreeItem[] = [ const mobileAvailableLaunchers: HiddenSubtreeItem[] = [
@ -103,11 +183,29 @@ export default function buildLaunchBarConfig() {
]; ];
const mobileVisibleLaunchers: HiddenSubtreeItem[] = [ const mobileVisibleLaunchers: HiddenSubtreeItem[] = [
{ id: "_lbMobileBackInHistory", ...sharedLaunchers.backInHistory }, {
{ id: "_lbMobileForwardInHistory", ...sharedLaunchers.forwardInHistory }, id: "_lbMobileBackInHistory",
{ id: "_lbMobileJumpTo", title: t("hidden-subtree.jump-to-note-title"), type: "launcher", command: "jumpToNote", icon: "bx bx-plus-circle" }, ...sharedLaunchers.backInHistory
{ id: "_lbMobileCalendar", ...sharedLaunchers.calendar }, },
{ id: "_lbMobileRecentChanges", ...sharedLaunchers.recentChanges } {
id: "_lbMobileForwardInHistory",
...sharedLaunchers.forwardInHistory
},
{
id: "_lbMobileJumpTo",
title: t("hidden-subtree.jump-to-note-title"),
type: "launcher",
command: "jumpToNote",
icon: "bx bx-plus-circle"
},
{
id: "_lbMobileCalendar",
...sharedLaunchers.calendar
},
{
id: "_lbMobileRecentChanges",
...sharedLaunchers.recentChanges
}
]; ];
return { return {

View File

@ -97,6 +97,23 @@ function copyChildAttributes(parentNote: BNote, childNote: BNote) {
} }
} }
function copyAttachments(origNote: BNote, newNote: BNote) {
for (const attachment of origNote.getAttachments()) {
if (attachment.role === "image") {
// Handled separately, see `checkImageAttachments`.
continue;
}
const newAttachment = new BAttachment({
...attachment,
attachmentId: undefined,
ownerId: newNote.noteId
});
newAttachment.save();
}
}
function getNewNoteTitle(parentNote: BNote) { function getNewNoteTitle(parentNote: BNote) {
let title = t("notes.new-note"); let title = t("notes.new-note");
@ -222,14 +239,14 @@ function createNewNote(params: NoteParams): {
} }
} }
asyncPostProcessContent(note, params.content);
if (params.templateNoteId) { if (params.templateNoteId) {
if (!becca.getNote(params.templateNoteId)) { const templateNote = becca.getNote(params.templateNoteId);
if (!templateNote) {
throw new Error(`Template note '${params.templateNoteId}' does not exist.`); throw new Error(`Template note '${params.templateNoteId}' does not exist.`);
} }
note.addRelation("template", params.templateNoteId); note.addRelation("template", params.templateNoteId);
copyAttachments(templateNote, note);
// no special handling for ~inherit since it doesn't matter if it's assigned with the note creation or later // no special handling for ~inherit since it doesn't matter if it's assigned with the note creation or later
} }
@ -1018,6 +1035,8 @@ function duplicateSubtreeInner(origNote: BNote, origBranch: BBranch | null | und
} }
} }
asyncPostProcessContent(newNote, content);
return newNote; return newNote;
} }

View File

@ -111,12 +111,13 @@ const defaultOptions: DefaultOption[] = [
{ name: "debugModeEnabled", value: "false", isSynced: false }, { name: "debugModeEnabled", value: "false", isSynced: false },
{ name: "headingStyle", value: "underline", isSynced: true }, { name: "headingStyle", value: "underline", isSynced: true },
{ name: "autoCollapseNoteTree", value: "true", isSynced: true }, { name: "autoCollapseNoteTree", value: "true", isSynced: true },
{ name: "autoReadonlySizeText", value: "10000", isSynced: false }, { name: "autoReadonlySizeText", value: "32000", isSynced: false },
{ name: "autoReadonlySizeCode", value: "30000", isSynced: false }, { name: "autoReadonlySizeCode", value: "64000", isSynced: false },
{ name: "dailyBackupEnabled", value: "true", isSynced: false }, { name: "dailyBackupEnabled", value: "true", isSynced: false },
{ name: "weeklyBackupEnabled", value: "true", isSynced: false }, { name: "weeklyBackupEnabled", value: "true", isSynced: false },
{ name: "monthlyBackupEnabled", value: "true", isSynced: false }, { name: "monthlyBackupEnabled", value: "true", isSynced: false },
{ name: "maxContentWidth", value: "1200", isSynced: false }, { name: "maxContentWidth", value: "1200", isSynced: false },
{ name: "centerContent", value: "false", isSynced: false },
{ name: "compressImages", value: "true", isSynced: true }, { name: "compressImages", value: "true", isSynced: true },
{ name: "downloadImagesAutomatically", value: "true", isSynced: true }, { name: "downloadImagesAutomatically", value: "true", isSynced: true },
{ name: "minTocHeadings", value: "5", isSynced: true }, { name: "minTocHeadings", value: "5", isSynced: true },

View File

@ -337,14 +337,15 @@ async function registerGlobalShortcuts() {
const result = globalShortcut.register( const result = globalShortcut.register(
translatedShortcut, translatedShortcut,
cls.wrap(() => { cls.wrap(() => {
if (!mainWindow) { const targetWindow = getLastFocusedWindow() || mainWindow;
if (!targetWindow || targetWindow.isDestroyed()) {
return; return;
} }
// window may be hidden / not in focus // window may be hidden / not in focus
mainWindow.focus(); showAndFocusWindow(targetWindow);
mainWindow.webContents.send("globalShortcut", action.actionName); targetWindow.webContents.send("globalShortcut", action.actionName);
}) })
); );
@ -358,6 +359,17 @@ async function registerGlobalShortcuts() {
} }
} }
function showAndFocusWindow(window: BrowserWindow) {
if (!window) return;
if (window.isMinimized()) {
window.restore();
}
window.show();
window.focus();
}
function getMainWindow() { function getMainWindow() {
return mainWindow; return mainWindow;
} }

View File

@ -9,7 +9,7 @@
"preview": "pnpm build && vite preview" "preview": "pnpm build && vite preview"
}, },
"dependencies": { "dependencies": {
"i18next": "25.6.0", "i18next": "25.6.1",
"i18next-http-backend": "3.0.2", "i18next-http-backend": "3.0.2",
"preact": "10.27.2", "preact": "10.27.2",
"preact-iso": "2.11.0", "preact-iso": "2.11.0",
@ -22,7 +22,7 @@
"eslint-config-preact": "2.0.0", "eslint-config-preact": "2.0.0",
"typescript": "5.9.3", "typescript": "5.9.3",
"user-agent-data-types": "0.4.2", "user-agent-data-types": "0.4.2",
"vite": "7.2.1" "vite": "7.2.2"
}, },
"eslintConfig": { "eslintConfig": {
"extends": "preact" "extends": "preact"

View File

@ -1,5 +1,5 @@
# Documentation # Documentation
There are multiple types of documentation for Trilium:<img class="image-style-align-right" src="api/images/kaFXA5t813qK/Documentation_image.png" width="205" height="162"> There are multiple types of documentation for Trilium:<img class="image-style-align-right" src="api/images/cWbjcMrvgaUn/Documentation_image.png" width="205" height="162">
* The _User Guide_ represents the user-facing documentation. This documentation can be browsed by users directly from within Trilium, by pressing <kbd>F1</kbd>. * The _User Guide_ represents the user-facing documentation. This documentation can be browsed by users directly from within Trilium, by pressing <kbd>F1</kbd>.
* The _Developer's Guide_ represents a set of Markdown documents that present the internals of Trilium, for developers. * The _Developer's Guide_ represents a set of Markdown documents that present the internals of Trilium, for developers.

View File

@ -4078,6 +4078,20 @@
"value": "printing-and-pdf-export", "value": "printing-and-pdf-export",
"isInheritable": false, "isInheritable": false,
"position": 110 "position": 110
},
{
"type": "relation",
"name": "internalLink",
"value": "bwZpz2ajCEwO",
"isInheritable": false,
"position": 120
},
{
"type": "relation",
"name": "internalLink",
"value": "KC1HB96bqqHX",
"isInheritable": false,
"position": 130
} }
], ],
"format": "markdown", "format": "markdown",
@ -11006,6 +11020,13 @@
"value": "bx bxs-file-css", "value": "bx bxs-file-css",
"isInheritable": false, "isInheritable": false,
"position": 50 "position": 50
},
{
"type": "relation",
"name": "internalLink",
"value": "NRnIZmSMc5sj",
"isInheritable": false,
"position": 60
} }
], ],
"format": "markdown", "format": "markdown",

View File

@ -64,11 +64,36 @@ Not all <a class="reference-link" href="../../Note%20Types.md">Note Types</a> 
* Line numbers are not printed. * Line numbers are not printed.
* Syntax highlighting is enabled, however a default theme (Visual Studio) is enforced. * Syntax highlighting is enabled, however a default theme (Visual Studio) is enforced.
* For <a class="reference-link" href="../../Collections.md">Collections</a>: * For <a class="reference-link" href="../../Collections.md">Collections</a>:
* Only <a class="reference-link" href="../../Collections/Presentation.md">Presentation View</a> is currently supported. * Only <a class="reference-link" href="../../Collections/Presentation.md">Presentation</a> is currently supported.
* We plan to add support for all the collection types at some point. * We plan to add support for all the collection types at some point.
* Using <a class="reference-link" href="../../Theme%20development/Custom%20app-wide%20CSS.md">Custom app-wide CSS</a> for printing is not longer supported, due to a more stable but isolated mechanism. * Using <a class="reference-link" href="../../Theme%20development/Custom%20app-wide%20CSS.md">Custom app-wide CSS</a> for printing is not longer supported, due to a more stable but isolated mechanism.
* We plan to introduce a new mechanism specifically for a print CSS. * We plan to introduce a new mechanism specifically for a print CSS.
## Customizing the print CSS
As an advanced use case, it's possible to customize the CSS used for printing such as adjusting the fonts, sizes or margins. Note that <a class="reference-link" href="../../Theme%20development/Custom%20app-wide%20CSS.md">Custom app-wide CSS</a> will not work for printing.
To do so:
* Create a CSS [code note](../../Note%20Types/Code.md).
* On the note being printed, apply the `~printCss` relation to point to the newly created CSS code note.
* To apply the CSS to multiple notes, consider using [inheritable attributes](../../Advanced%20Usage/Attributes/Attribute%20Inheritance.md) or <a class="reference-link" href="../../Advanced%20Usage/Templates.md">Templates</a>.
For example, to change the font of the document from the one defined by the theme or the user to a serif one:
```
body {
--main-font-family: serif !important;
--detail-font-family: var(--main-font-family) !important;
}
```
To remark:
* Multiple CSS notes can be add by using multiple `~printCss` relations.
* If the note pointing to the `printCss` doesn't have the right note type or mime type, it will be ignored.
* If migrating from a previous version where <a class="reference-link" href="../../Theme%20development/Custom%20app-wide%20CSS.md">Custom app-wide CSS</a>, there's no need for `@media print {` since the style-sheet is used only for printing.
## Under the hood ## Under the hood
Both printing and exporting as PDF use the same mechanism: a note is rendered individually in a separate webpage that is then sent to the browser or the Electron application either for printing or exporting as PDF. Both printing and exporting as PDF use the same mechanism: a note is rendered individually in a separate webpage that is then sent to the browser or the Electron application either for printing or exporting as PDF.

View File

@ -5,7 +5,7 @@ It is possible to provide a CSS file to be used regardless of the theme set by t
| --- | --- | | --- | --- |
| ![](Custom%20app-wide%20CSS_image.png) | Start by creating a new note and changing the note type to CSS | | ![](Custom%20app-wide%20CSS_image.png) | Start by creating a new note and changing the note type to CSS |
| ![](2_Custom%20app-wide%20CSS_image.png) | In the ribbon, press the “Owned Attributes” section and type `#appCss`. | | ![](2_Custom%20app-wide%20CSS_image.png) | In the ribbon, press the “Owned Attributes” section and type `#appCss`. |
| ![](3_Custom%20app-wide%20CSS_image.png) | Type the desired CSS.   <br> <br>Generally it's a good idea to append `!important` for the styles that are being changed, in order to prevent other | | ![](3_Custom%20app-wide%20CSS_image.png) | Type the desired CSS.    <br> <br>Generally it's a good idea to append `!important` for the styles that are being changed, in order to prevent other |
## Seeing the changes ## Seeing the changes
@ -15,18 +15,10 @@ Adding a new _app CSS note_ or modifying an existing one does not immediately ap
### Customizing the printing stylesheet ### Customizing the printing stylesheet
When printing a document or exporting as PDF, it is possible to adjust the style by creating a CSS note that uses the `@media`selector. > [!TIP]
> Since v0.99.2, it's no longer possible to use `#appCss` to customize the printing CSS, since the printing is now done in an isolated environment.
For example, to change the font of the document from the one defined by the theme or the user to a serif one: >
> However, it's still possible to customize the CSS via `~printCss`; see <a class="reference-link" href="../Basic%20Concepts%20and%20Features/Notes/Printing%20%26%20Exporting%20as%20PDF.md">Printing &amp; Exporting as PDF</a> for more information.
```
@media print {
body {
--main-font-family: serif !important;
--detail-font-family: var(--main-font-family) !important;
}
}
```
### Per-workspace styles ### Per-workspace styles
@ -84,4 +76,4 @@ To change the color of the note title and the icon (above the content):
Some parts of the application can't be styled directly via custom CSS because they are rendered in an isolated mode (shadow DOM), more specifically: Some parts of the application can't be styled directly via custom CSS because they are rendered in an isolated mode (shadow DOM), more specifically:
* The slides in a <a class="reference-link" href="../Collections/Presentation.md">Presentation View</a>. * The slides in a <a class="reference-link" href="../Collections/Presentation.md">Presentation</a>.

View File

@ -65,7 +65,7 @@
"typescript": "~5.9.0", "typescript": "~5.9.0",
"typescript-eslint": "8.46.3", "typescript-eslint": "8.46.3",
"upath": "2.0.1", "upath": "2.0.1",
"vite": "7.2.1", "vite": "7.2.2",
"vite-plugin-dts": "~4.5.0", "vite-plugin-dts": "~4.5.0",
"vitest": "3.2.4" "vitest": "3.2.4"
}, },

View File

@ -6,7 +6,9 @@ enum Command {
createNoteIntoInbox, createNoteIntoInbox,
showRecentChanges, showRecentChanges,
showOptions, showOptions,
createAiChat createAiChat,
commandPalette,
toggleZenMode
} }
export interface HiddenSubtreeAttribute { export interface HiddenSubtreeAttribute {
@ -41,7 +43,9 @@ export interface HiddenSubtreeItem {
| "protectedSession" | "protectedSession"
| "calendar" | "calendar"
| "quickSearch" | "quickSearch"
| "aiChatLauncher"; | "aiChatLauncher"
| "commandPalette"
| "toggleZenMode";
command?: keyof typeof Command; command?: keyof typeof Command;
/** /**
* If set to true, then branches will be enforced to be in the correct place. * If set to true, then branches will be enforced to be in the correct place.

View File

@ -82,6 +82,7 @@ export interface OptionDefinitions extends KeyboardShortcutsOptions<KeyboardActi
autoReadonlySizeText: number; autoReadonlySizeText: number;
autoReadonlySizeCode: number; autoReadonlySizeCode: number;
maxContentWidth: number; maxContentWidth: number;
centerContent: boolean;
minTocHeadings: number; minTocHeadings: number;
eraseUnusedAttachmentsAfterSeconds: number; eraseUnusedAttachmentsAfterSeconds: number;
eraseUnusedAttachmentsAfterTimeScale: number; eraseUnusedAttachmentsAfterTimeScale: number;

View File

@ -12,7 +12,7 @@ export interface AttachmentRow {
isProtected?: boolean; isProtected?: boolean;
dateModified?: string; dateModified?: string;
utcDateModified?: string; utcDateModified?: string;
utcDateScheduledForErasureSince?: string; utcDateScheduledForErasureSince?: string | null;
isDeleted?: boolean; isDeleted?: boolean;
deleteId?: string; deleteId?: string;
contentLength?: number; contentLength?: number;

186
pnpm-lock.yaml generated
View File

@ -102,7 +102,7 @@ importers:
version: 0.18.0 version: 0.18.0
rollup-plugin-webpack-stats: rollup-plugin-webpack-stats:
specifier: 2.1.7 specifier: 2.1.7
version: 2.1.7(rolldown@1.0.0-beta.29)(rollup@4.52.0)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) version: 2.1.7(rolldown@1.0.0-beta.29)(rollup@4.52.0)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
tslib: tslib:
specifier: 2.8.1 specifier: 2.8.1
version: 2.8.1 version: 2.8.1
@ -119,11 +119,11 @@ importers:
specifier: 2.0.1 specifier: 2.0.1
version: 2.0.1 version: 2.0.1
vite: vite:
specifier: 7.2.1 specifier: 7.2.2
version: 7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) version: 7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
vite-plugin-dts: vite-plugin-dts:
specifier: ~4.5.0 specifier: ~4.5.0
version: 4.5.4(@types/node@24.10.0)(rollup@4.52.0)(typescript@5.9.3)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) version: 4.5.4(@types/node@24.10.0)(rollup@4.52.0)(typescript@5.9.3)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
vitest: vitest:
specifier: 3.2.4 specifier: 3.2.4
version: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.0)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) version: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.0)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
@ -239,8 +239,8 @@ importers:
specifier: 16.5.0 specifier: 16.5.0
version: 16.5.0 version: 16.5.0
i18next: i18next:
specifier: 25.6.0 specifier: 25.6.1
version: 25.6.0(typescript@5.9.3) version: 25.6.1(typescript@5.9.3)
i18next-http-backend: i18next-http-backend:
specifier: 3.0.2 specifier: 3.0.2
version: 3.0.2(encoding@0.1.13) version: 3.0.2(encoding@0.1.13)
@ -269,8 +269,8 @@ importers:
specifier: 8.11.1 specifier: 8.11.1
version: 8.11.1 version: 8.11.1
marked: marked:
specifier: 16.4.1 specifier: 16.4.2
version: 16.4.1 version: 16.4.2
mermaid: mermaid:
specifier: 11.12.1 specifier: 11.12.1
version: 11.12.1 version: 11.12.1
@ -288,7 +288,7 @@ importers:
version: 10.27.2 version: 10.27.2
react-i18next: react-i18next:
specifier: 16.2.4 specifier: 16.2.4
version: 16.2.4(i18next@25.6.0(typescript@5.9.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.9.3) version: 16.2.4(i18next@25.6.1(typescript@5.9.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
reveal.js: reveal.js:
specifier: 5.2.1 specifier: 5.2.1
version: 5.2.1 version: 5.2.1
@ -307,7 +307,7 @@ importers:
version: 5.0.0 version: 5.0.0
'@preact/preset-vite': '@preact/preset-vite':
specifier: 2.10.2 specifier: 2.10.2
version: 2.10.2(@babel/core@7.28.0)(preact@10.27.2)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) version: 2.10.2(@babel/core@7.28.0)(preact@10.27.2)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
'@types/bootstrap': '@types/bootstrap':
specifier: 5.2.10 specifier: 5.2.10
version: 5.2.10 version: 5.2.10
@ -340,7 +340,7 @@ importers:
version: 0.7.2 version: 0.7.2
vite-plugin-static-copy: vite-plugin-static-copy:
specifier: 3.1.4 specifier: 3.1.4
version: 3.1.4(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) version: 3.1.4(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
apps/db-compare: apps/db-compare:
dependencies: dependencies:
@ -361,7 +361,7 @@ importers:
dependencies: dependencies:
'@electron/remote': '@electron/remote':
specifier: 2.1.3 specifier: 2.1.3
version: 2.1.3(electron@38.5.0) version: 2.1.3(electron@38.6.0)
better-sqlite3: better-sqlite3:
specifier: 12.4.1 specifier: 12.4.1
version: 12.4.1 version: 12.4.1
@ -418,8 +418,8 @@ importers:
specifier: 13.0.1 specifier: 13.0.1
version: 13.0.1(webpack@5.101.3(esbuild@0.25.12)) version: 13.0.1(webpack@5.101.3(esbuild@0.25.12))
electron: electron:
specifier: 38.5.0 specifier: 38.6.0
version: 38.5.0 version: 38.6.0
prebuild-install: prebuild-install:
specifier: 7.1.3 specifier: 7.1.3
version: 7.1.3 version: 7.1.3
@ -474,8 +474,8 @@ importers:
specifier: 13.0.1 specifier: 13.0.1
version: 13.0.1(webpack@5.101.3(esbuild@0.25.12)) version: 13.0.1(webpack@5.101.3(esbuild@0.25.12))
electron: electron:
specifier: 38.5.0 specifier: 38.6.0
version: 38.5.0 version: 38.6.0
fs-extra: fs-extra:
specifier: 11.3.2 specifier: 11.3.2
version: 11.3.2 version: 11.3.2
@ -500,10 +500,10 @@ importers:
version: 7.1.1 version: 7.1.1
'@electron/remote': '@electron/remote':
specifier: 2.1.3 specifier: 2.1.3
version: 2.1.3(electron@38.5.0) version: 2.1.3(electron@38.6.0)
'@preact/preset-vite': '@preact/preset-vite':
specifier: 2.10.2 specifier: 2.10.2
version: 2.10.2(@babel/core@7.28.0)(preact@10.27.2)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) version: 2.10.2(@babel/core@7.28.0)(preact@10.27.2)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
'@triliumnext/commons': '@triliumnext/commons':
specifier: workspace:* specifier: workspace:*
version: link:../../packages/commons version: link:../../packages/commons
@ -646,8 +646,8 @@ importers:
specifier: 3.1.10 specifier: 3.1.10
version: 3.1.10 version: 3.1.10
electron: electron:
specifier: 38.5.0 specifier: 38.6.0
version: 38.5.0 version: 38.6.0
electron-debug: electron-debug:
specifier: 4.1.0 specifier: 4.1.0
version: 4.1.0 version: 4.1.0
@ -694,8 +694,8 @@ importers:
specifier: 7.0.6 specifier: 7.0.6
version: 7.0.6 version: 7.0.6
i18next: i18next:
specifier: 25.6.0 specifier: 25.6.1
version: 25.6.0(typescript@5.9.3) version: 25.6.1(typescript@5.9.3)
i18next-fs-backend: i18next-fs-backend:
specifier: 2.6.0 specifier: 2.6.0
version: 2.6.0 version: 2.6.0
@ -718,8 +718,8 @@ importers:
specifier: 4.1.0 specifier: 4.1.0
version: 4.1.0 version: 4.1.0
marked: marked:
specifier: 16.4.1 specifier: 16.4.2
version: 16.4.1 version: 16.4.2
mime-types: mime-types:
specifier: 3.0.1 specifier: 3.0.1
version: 3.0.1 version: 3.0.1
@ -781,8 +781,8 @@ importers:
specifier: 1.0.1 specifier: 1.0.1
version: 1.0.1 version: 1.0.1
vite: vite:
specifier: 7.2.1 specifier: 7.2.2
version: 7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) version: 7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
ws: ws:
specifier: 8.18.3 specifier: 8.18.3
version: 8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.5) version: 8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.5)
@ -802,8 +802,8 @@ importers:
apps/website: apps/website:
dependencies: dependencies:
i18next: i18next:
specifier: 25.6.0 specifier: 25.6.1
version: 25.6.0(typescript@5.9.3) version: 25.6.1(typescript@5.9.3)
i18next-http-backend: i18next-http-backend:
specifier: 3.0.2 specifier: 3.0.2
version: 3.0.2(encoding@0.1.13) version: 3.0.2(encoding@0.1.13)
@ -818,11 +818,11 @@ importers:
version: 6.6.3(preact@10.27.2) version: 6.6.3(preact@10.27.2)
react-i18next: react-i18next:
specifier: 16.2.4 specifier: 16.2.4
version: 16.2.4(i18next@25.6.0(typescript@5.9.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.9.3) version: 16.2.4(i18next@25.6.1(typescript@5.9.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
devDependencies: devDependencies:
'@preact/preset-vite': '@preact/preset-vite':
specifier: 2.10.2 specifier: 2.10.2
version: 2.10.2(@babel/core@7.28.0)(preact@10.27.2)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) version: 2.10.2(@babel/core@7.28.0)(preact@10.27.2)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
eslint: eslint:
specifier: 9.39.1 specifier: 9.39.1
version: 9.39.1(jiti@2.6.1) version: 9.39.1(jiti@2.6.1)
@ -836,8 +836,8 @@ importers:
specifier: 0.4.2 specifier: 0.4.2
version: 0.4.2 version: 0.4.2
vite: vite:
specifier: 7.2.1 specifier: 7.2.2
version: 7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) version: 7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
packages/ckeditor5: packages/ckeditor5:
dependencies: dependencies:
@ -889,7 +889,7 @@ importers:
version: 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) version: 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
'@vitest/browser': '@vitest/browser':
specifier: 3.2.4 specifier: 3.2.4
version: 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(playwright@1.56.1)(utf-8-validate@6.0.5)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)) version: 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(playwright@1.56.1)(utf-8-validate@6.0.5)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))
'@vitest/coverage-istanbul': '@vitest/coverage-istanbul':
specifier: 3.2.4 specifier: 3.2.4
version: 3.2.4(vitest@3.2.4) version: 3.2.4(vitest@3.2.4)
@ -922,7 +922,7 @@ importers:
version: 5.9.3 version: 5.9.3
vite-plugin-svgo: vite-plugin-svgo:
specifier: ~2.0.0 specifier: ~2.0.0
version: 2.0.0(typescript@5.9.3)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) version: 2.0.0(typescript@5.9.3)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
vitest: vitest:
specifier: 3.2.4 specifier: 3.2.4
version: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.0)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) version: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.0)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
@ -949,7 +949,7 @@ importers:
version: 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) version: 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
'@vitest/browser': '@vitest/browser':
specifier: 3.2.4 specifier: 3.2.4
version: 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(playwright@1.56.1)(utf-8-validate@6.0.5)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)) version: 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(playwright@1.56.1)(utf-8-validate@6.0.5)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))
'@vitest/coverage-istanbul': '@vitest/coverage-istanbul':
specifier: 3.2.4 specifier: 3.2.4
version: 3.2.4(vitest@3.2.4) version: 3.2.4(vitest@3.2.4)
@ -982,7 +982,7 @@ importers:
version: 5.9.3 version: 5.9.3
vite-plugin-svgo: vite-plugin-svgo:
specifier: ~2.0.0 specifier: ~2.0.0
version: 2.0.0(typescript@5.9.3)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) version: 2.0.0(typescript@5.9.3)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
vitest: vitest:
specifier: 3.2.4 specifier: 3.2.4
version: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.0)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) version: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.0)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
@ -1009,7 +1009,7 @@ importers:
version: 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) version: 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
'@vitest/browser': '@vitest/browser':
specifier: 3.2.4 specifier: 3.2.4
version: 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(playwright@1.56.1)(utf-8-validate@6.0.5)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)) version: 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(playwright@1.56.1)(utf-8-validate@6.0.5)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))
'@vitest/coverage-istanbul': '@vitest/coverage-istanbul':
specifier: 3.2.4 specifier: 3.2.4
version: 3.2.4(vitest@3.2.4) version: 3.2.4(vitest@3.2.4)
@ -1042,7 +1042,7 @@ importers:
version: 5.9.3 version: 5.9.3
vite-plugin-svgo: vite-plugin-svgo:
specifier: ~2.0.0 specifier: ~2.0.0
version: 2.0.0(typescript@5.9.3)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) version: 2.0.0(typescript@5.9.3)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
vitest: vitest:
specifier: 3.2.4 specifier: 3.2.4
version: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.0)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) version: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.0)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
@ -1076,7 +1076,7 @@ importers:
version: 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) version: 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
'@vitest/browser': '@vitest/browser':
specifier: 3.2.4 specifier: 3.2.4
version: 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(playwright@1.56.1)(utf-8-validate@6.0.5)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)) version: 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(playwright@1.56.1)(utf-8-validate@6.0.5)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))
'@vitest/coverage-istanbul': '@vitest/coverage-istanbul':
specifier: 3.2.4 specifier: 3.2.4
version: 3.2.4(vitest@3.2.4) version: 3.2.4(vitest@3.2.4)
@ -1109,7 +1109,7 @@ importers:
version: 5.9.3 version: 5.9.3
vite-plugin-svgo: vite-plugin-svgo:
specifier: ~2.0.0 specifier: ~2.0.0
version: 2.0.0(typescript@5.9.3)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) version: 2.0.0(typescript@5.9.3)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
vitest: vitest:
specifier: 3.2.4 specifier: 3.2.4
version: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.0)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) version: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.0)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
@ -1143,7 +1143,7 @@ importers:
version: 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) version: 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
'@vitest/browser': '@vitest/browser':
specifier: 3.2.4 specifier: 3.2.4
version: 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(playwright@1.56.1)(utf-8-validate@6.0.5)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)) version: 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(playwright@1.56.1)(utf-8-validate@6.0.5)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))
'@vitest/coverage-istanbul': '@vitest/coverage-istanbul':
specifier: 3.2.4 specifier: 3.2.4
version: 3.2.4(vitest@3.2.4) version: 3.2.4(vitest@3.2.4)
@ -1176,7 +1176,7 @@ importers:
version: 5.9.3 version: 5.9.3
vite-plugin-svgo: vite-plugin-svgo:
specifier: ~2.0.0 specifier: ~2.0.0
version: 2.0.0(typescript@5.9.3)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) version: 2.0.0(typescript@5.9.3)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
vitest: vitest:
specifier: 3.2.4 specifier: 3.2.4
version: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.0)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) version: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.0)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
@ -7619,8 +7619,8 @@ packages:
resolution: {integrity: sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==} resolution: {integrity: sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==}
engines: {node: '>=8.0.0'} engines: {node: '>=8.0.0'}
electron@38.5.0: electron@38.6.0:
resolution: {integrity: sha512-dbC7V+eZweerYMJfxQldzHOg37a1VdNMCKxrJxlkp3cA30gOXtXSg4ZYs07L5+QwI19WOy1uyvtEUgbw1RRsCQ==} resolution: {integrity: sha512-68OFNxJlrEStA+t8k5atzf4frJddvRR1N1oalr49Ll8YZ0+0nEsDhw4UNhTCoZKTjSYcxFF/4rt+sco+OlnB3g==}
engines: {node: '>= 12.20.55'} engines: {node: '>= 12.20.55'}
hasBin: true hasBin: true
@ -8860,8 +8860,8 @@ packages:
i18next-http-backend@3.0.2: i18next-http-backend@3.0.2:
resolution: {integrity: sha512-PdlvPnvIp4E1sYi46Ik4tBYh/v/NbYfFFgTjkwFl0is8A18s7/bx9aXqsrOax9WUbeNS6mD2oix7Z0yGGf6m5g==} resolution: {integrity: sha512-PdlvPnvIp4E1sYi46Ik4tBYh/v/NbYfFFgTjkwFl0is8A18s7/bx9aXqsrOax9WUbeNS6mD2oix7Z0yGGf6m5g==}
i18next@25.6.0: i18next@25.6.1:
resolution: {integrity: sha512-tTn8fLrwBYtnclpL5aPXK/tAYBLWVvoHM1zdfXoRNLcI+RvtMsoZRV98ePlaW3khHYKuNh/Q65W/+NVFUeIwVw==} resolution: {integrity: sha512-yUWvdXtalZztmKrKw3yz/AvSP3yKyqIkVPx/wyvoYy9lkLmwzItLxp0iHZLG5hfVQ539Jor4XLO+U+NHIXg7pw==}
peerDependencies: peerDependencies:
typescript: ^5 typescript: ^5
peerDependenciesMeta: peerDependenciesMeta:
@ -9954,8 +9954,8 @@ packages:
markdown-table@3.0.4: markdown-table@3.0.4:
resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
marked@16.4.1: marked@16.4.2:
resolution: {integrity: sha512-ntROs7RaN3EvWfy3EZi14H4YxmT6A5YvywfhO+0pm+cH/dnSQRmdAmoFIc3B9aiwTehyk7pESH4ofyBY+V5hZg==} resolution: {integrity: sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==}
engines: {node: '>= 20'} engines: {node: '>= 20'}
hasBin: true hasBin: true
@ -14139,8 +14139,8 @@ packages:
peerDependencies: peerDependencies:
vite: 5.x || 6.x || 7.x vite: 5.x || 6.x || 7.x
vite@7.2.1: vite@7.2.2:
resolution: {integrity: sha512-qTl3VF7BvOupTR85Zc561sPEgxyUSNSvTQ9fit7DEMP7yPgvvIGm5Zfa1dOM+kOwWGNviK9uFM9ra77+OjK7lQ==} resolution: {integrity: sha512-BxAKBWmIbrDgrokdGZH1IgkIk/5mMHDreLDmCJ0qpyJaAteP8NvMhkwr/ZCQNqNH97bw/dANTE9PDzqwJghfMQ==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
@ -15369,6 +15369,8 @@ snapshots:
'@ckeditor/ckeditor5-core': 47.2.0 '@ckeditor/ckeditor5-core': 47.2.0
'@ckeditor/ckeditor5-upload': 47.2.0 '@ckeditor/ckeditor5-upload': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41) ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
transitivePeerDependencies:
- supports-color
'@ckeditor/ckeditor5-ai@47.2.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)': '@ckeditor/ckeditor5-ai@47.2.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)':
dependencies: dependencies:
@ -15579,8 +15581,6 @@ snapshots:
'@ckeditor/ckeditor5-utils': 47.2.0 '@ckeditor/ckeditor5-utils': 47.2.0
'@ckeditor/ckeditor5-watchdog': 47.2.0 '@ckeditor/ckeditor5-watchdog': 47.2.0
es-toolkit: 1.39.5 es-toolkit: 1.39.5
transitivePeerDependencies:
- supports-color
'@ckeditor/ckeditor5-dev-build-tools@43.1.0(@swc/helpers@0.5.17)(tslib@2.8.1)(typescript@5.9.3)': '@ckeditor/ckeditor5-dev-build-tools@43.1.0(@swc/helpers@0.5.17)(tslib@2.8.1)(typescript@5.9.3)':
dependencies: dependencies:
@ -15796,8 +15796,6 @@ snapshots:
'@ckeditor/ckeditor5-table': 47.2.0 '@ckeditor/ckeditor5-table': 47.2.0
'@ckeditor/ckeditor5-utils': 47.2.0 '@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41) ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
transitivePeerDependencies:
- supports-color
'@ckeditor/ckeditor5-emoji@47.2.0': '@ckeditor/ckeditor5-emoji@47.2.0':
dependencies: dependencies:
@ -15982,8 +15980,6 @@ snapshots:
'@ckeditor/ckeditor5-widget': 47.2.0 '@ckeditor/ckeditor5-widget': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41) ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
es-toolkit: 1.39.5 es-toolkit: 1.39.5
transitivePeerDependencies:
- supports-color
'@ckeditor/ckeditor5-icons@47.2.0': {} '@ckeditor/ckeditor5-icons@47.2.0': {}
@ -16283,8 +16279,6 @@ snapshots:
'@ckeditor/ckeditor5-ui': 47.2.0 '@ckeditor/ckeditor5-ui': 47.2.0
'@ckeditor/ckeditor5-utils': 47.2.0 '@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41) ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
transitivePeerDependencies:
- supports-color
'@ckeditor/ckeditor5-restricted-editing@47.2.0': '@ckeditor/ckeditor5-restricted-editing@47.2.0':
dependencies: dependencies:
@ -17129,9 +17123,9 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@electron/remote@2.1.3(electron@38.5.0)': '@electron/remote@2.1.3(electron@38.6.0)':
dependencies: dependencies:
electron: 38.5.0 electron: 38.6.0
'@electron/universal@2.0.2': '@electron/universal@2.0.2':
dependencies: dependencies:
@ -18648,18 +18642,18 @@ snapshots:
'@popperjs/core@2.11.8': {} '@popperjs/core@2.11.8': {}
'@preact/preset-vite@2.10.2(@babel/core@7.28.0)(preact@10.27.2)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': '@preact/preset-vite@2.10.2(@babel/core@7.28.0)(preact@10.27.2)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))':
dependencies: dependencies:
'@babel/core': 7.28.0 '@babel/core': 7.28.0
'@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.0) '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.0)
'@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.0) '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.0)
'@prefresh/vite': 2.4.8(preact@10.27.2)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) '@prefresh/vite': 2.4.8(preact@10.27.2)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
'@rollup/pluginutils': 4.2.1 '@rollup/pluginutils': 4.2.1
babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.28.0) babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.28.0)
debug: 4.4.1 debug: 4.4.1
picocolors: 1.1.1 picocolors: 1.1.1
vite: 7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vite: 7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
vite-prerender-plugin: 0.5.11(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) vite-prerender-plugin: 0.5.11(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
transitivePeerDependencies: transitivePeerDependencies:
- preact - preact
- supports-color - supports-color
@ -18672,7 +18666,7 @@ snapshots:
'@prefresh/utils@1.2.1': {} '@prefresh/utils@1.2.1': {}
'@prefresh/vite@2.4.8(preact@10.27.2)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': '@prefresh/vite@2.4.8(preact@10.27.2)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))':
dependencies: dependencies:
'@babel/core': 7.28.0 '@babel/core': 7.28.0
'@prefresh/babel-plugin': 0.5.2 '@prefresh/babel-plugin': 0.5.2
@ -18680,7 +18674,7 @@ snapshots:
'@prefresh/utils': 1.2.1 '@prefresh/utils': 1.2.1
'@rollup/pluginutils': 4.2.1 '@rollup/pluginutils': 4.2.1
preact: 10.27.2 preact: 10.27.2
vite: 7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vite: 7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -20716,11 +20710,11 @@ snapshots:
- bufferutil - bufferutil
- utf-8-validate - utf-8-validate
'@vitest/browser@3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(playwright@1.56.1)(utf-8-validate@6.0.5)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))': '@vitest/browser@3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(playwright@1.56.1)(utf-8-validate@6.0.5)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))':
dependencies: dependencies:
'@testing-library/dom': 10.4.0 '@testing-library/dom': 10.4.0
'@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.0) '@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.0)
'@vitest/mocker': 3.2.4(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) '@vitest/mocker': 3.2.4(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
'@vitest/utils': 3.2.4 '@vitest/utils': 3.2.4
magic-string: 0.30.18 magic-string: 0.30.18
sirv: 3.0.1 sirv: 3.0.1
@ -20769,7 +20763,7 @@ snapshots:
tinyrainbow: 2.0.0 tinyrainbow: 2.0.0
vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.0)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.0)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
optionalDependencies: optionalDependencies:
'@vitest/browser': 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(playwright@1.56.1)(utf-8-validate@6.0.5)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)) '@vitest/browser': 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(playwright@1.56.1)(utf-8-validate@6.0.5)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -20781,14 +20775,14 @@ snapshots:
chai: 5.2.0 chai: 5.2.0
tinyrainbow: 2.0.0 tinyrainbow: 2.0.0
'@vitest/mocker@3.2.4(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': '@vitest/mocker@3.2.4(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))':
dependencies: dependencies:
'@vitest/spy': 3.2.4 '@vitest/spy': 3.2.4
estree-walker: 3.0.3 estree-walker: 3.0.3
magic-string: 0.30.18 magic-string: 0.30.18
optionalDependencies: optionalDependencies:
msw: 2.7.5(@types/node@24.10.0)(typescript@5.9.3) msw: 2.7.5(@types/node@24.10.0)(typescript@5.9.3)
vite: 7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vite: 7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
'@vitest/pretty-format@3.2.4': '@vitest/pretty-format@3.2.4':
dependencies: dependencies:
@ -23353,10 +23347,10 @@ snapshots:
- supports-color - supports-color
optional: true optional: true
electron@38.5.0: electron@38.6.0:
dependencies: dependencies:
'@electron/get': 2.0.3 '@electron/get': 2.0.3
'@types/node': 22.18.12 '@types/node': 22.18.13
extract-zip: 2.0.1 extract-zip: 2.0.1
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -25146,7 +25140,7 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- encoding - encoding
i18next@25.6.0(typescript@5.9.3): i18next@25.6.1(typescript@5.9.3):
dependencies: dependencies:
'@babel/runtime': 7.28.4 '@babel/runtime': 7.28.4
optionalDependencies: optionalDependencies:
@ -26340,7 +26334,7 @@ snapshots:
markdown-table@3.0.4: {} markdown-table@3.0.4: {}
marked@16.4.1: {} marked@16.4.2: {}
marked@4.3.0: {} marked@4.3.0: {}
@ -26539,7 +26533,7 @@ snapshots:
katex: 0.16.25 katex: 0.16.25
khroma: 2.1.0 khroma: 2.1.0
lodash-es: 4.17.21 lodash-es: 4.17.21
marked: 16.4.1 marked: 16.4.2
roughjs: 4.6.6 roughjs: 4.6.6
stylis: 4.3.6 stylis: 4.3.6
ts-dedent: 2.2.0 ts-dedent: 2.2.0
@ -28803,11 +28797,11 @@ snapshots:
react: 19.2.0 react: 19.2.0
scheduler: 0.27.0 scheduler: 0.27.0
react-i18next@16.2.4(i18next@25.6.0(typescript@5.9.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.9.3): react-i18next@16.2.4(i18next@25.6.1(typescript@5.9.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.9.3):
dependencies: dependencies:
'@babel/runtime': 7.28.4 '@babel/runtime': 7.28.4
html-parse-stringify: 3.0.1 html-parse-stringify: 3.0.1
i18next: 25.6.0(typescript@5.9.3) i18next: 25.6.1(typescript@5.9.3)
react: 19.2.0 react: 19.2.0
use-sync-external-store: 1.6.0(react@19.2.0) use-sync-external-store: 1.6.0(react@19.2.0)
optionalDependencies: optionalDependencies:
@ -29230,11 +29224,11 @@ snapshots:
'@rolldown/binding-win32-x64-msvc': 1.0.0-beta.29 '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.29
optional: true optional: true
rollup-plugin-stats@1.5.2(rolldown@1.0.0-beta.29)(rollup@4.52.0)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): rollup-plugin-stats@1.5.2(rolldown@1.0.0-beta.29)(rollup@4.52.0)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)):
optionalDependencies: optionalDependencies:
rolldown: 1.0.0-beta.29 rolldown: 1.0.0-beta.29
rollup: 4.52.0 rollup: 4.52.0
vite: 7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vite: 7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
rollup-plugin-styles@4.0.0(rollup@4.40.0): rollup-plugin-styles@4.0.0(rollup@4.40.0):
dependencies: dependencies:
@ -29263,13 +29257,13 @@ snapshots:
'@rollup/pluginutils': 5.1.4(rollup@4.40.0) '@rollup/pluginutils': 5.1.4(rollup@4.40.0)
rollup: 4.40.0 rollup: 4.40.0
rollup-plugin-webpack-stats@2.1.7(rolldown@1.0.0-beta.29)(rollup@4.52.0)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): rollup-plugin-webpack-stats@2.1.7(rolldown@1.0.0-beta.29)(rollup@4.52.0)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)):
dependencies: dependencies:
rollup-plugin-stats: 1.5.2(rolldown@1.0.0-beta.29)(rollup@4.52.0)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) rollup-plugin-stats: 1.5.2(rolldown@1.0.0-beta.29)(rollup@4.52.0)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
optionalDependencies: optionalDependencies:
rolldown: 1.0.0-beta.29 rolldown: 1.0.0-beta.29
rollup: 4.52.0 rollup: 4.52.0
vite: 7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vite: 7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
rollup@4.40.0: rollup@4.40.0:
dependencies: dependencies:
@ -31271,7 +31265,7 @@ snapshots:
debug: 4.4.3(supports-color@6.0.0) debug: 4.4.3(supports-color@6.0.0)
es-module-lexer: 1.7.0 es-module-lexer: 1.7.0
pathe: 2.0.3 pathe: 2.0.3
vite: 7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vite: 7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
transitivePeerDependencies: transitivePeerDependencies:
- '@types/node' - '@types/node'
- jiti - jiti
@ -31286,7 +31280,7 @@ snapshots:
- tsx - tsx
- yaml - yaml
vite-plugin-dts@4.5.4(@types/node@24.10.0)(rollup@4.52.0)(typescript@5.9.3)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): vite-plugin-dts@4.5.4(@types/node@24.10.0)(rollup@4.52.0)(typescript@5.9.3)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)):
dependencies: dependencies:
'@microsoft/api-extractor': 7.52.8(@types/node@24.10.0) '@microsoft/api-extractor': 7.52.8(@types/node@24.10.0)
'@rollup/pluginutils': 5.1.4(rollup@4.52.0) '@rollup/pluginutils': 5.1.4(rollup@4.52.0)
@ -31299,27 +31293,27 @@ snapshots:
magic-string: 0.30.17 magic-string: 0.30.17
typescript: 5.9.3 typescript: 5.9.3
optionalDependencies: optionalDependencies:
vite: 7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vite: 7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
transitivePeerDependencies: transitivePeerDependencies:
- '@types/node' - '@types/node'
- rollup - rollup
- supports-color - supports-color
vite-plugin-static-copy@3.1.4(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): vite-plugin-static-copy@3.1.4(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)):
dependencies: dependencies:
chokidar: 3.6.0 chokidar: 3.6.0
p-map: 7.0.3 p-map: 7.0.3
picocolors: 1.1.1 picocolors: 1.1.1
tinyglobby: 0.2.15 tinyglobby: 0.2.15
vite: 7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vite: 7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
vite-plugin-svgo@2.0.0(typescript@5.9.3)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): vite-plugin-svgo@2.0.0(typescript@5.9.3)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)):
dependencies: dependencies:
svgo: 3.3.2 svgo: 3.3.2
typescript: 5.9.3 typescript: 5.9.3
vite: 7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vite: 7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
vite-prerender-plugin@0.5.11(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)): vite-prerender-plugin@0.5.11(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)):
dependencies: dependencies:
kolorist: 1.8.0 kolorist: 1.8.0
magic-string: 0.30.18 magic-string: 0.30.18
@ -31327,9 +31321,9 @@ snapshots:
simple-code-frame: 1.3.0 simple-code-frame: 1.3.0
source-map: 0.7.6 source-map: 0.7.6
stack-trace: 1.0.0-pre2 stack-trace: 1.0.0-pre2
vite: 7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vite: 7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1):
dependencies: dependencies:
esbuild: 0.25.12 esbuild: 0.25.12
fdir: 6.5.0(picomatch@4.0.3) fdir: 6.5.0(picomatch@4.0.3)
@ -31353,7 +31347,7 @@ snapshots:
dependencies: dependencies:
'@types/chai': 5.2.2 '@types/chai': 5.2.2
'@vitest/expect': 3.2.4 '@vitest/expect': 3.2.4
'@vitest/mocker': 3.2.4(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) '@vitest/mocker': 3.2.4(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
'@vitest/pretty-format': 3.2.4 '@vitest/pretty-format': 3.2.4
'@vitest/runner': 3.2.4 '@vitest/runner': 3.2.4
'@vitest/snapshot': 3.2.4 '@vitest/snapshot': 3.2.4
@ -31371,13 +31365,13 @@ snapshots:
tinyglobby: 0.2.15 tinyglobby: 0.2.15
tinypool: 1.1.1 tinypool: 1.1.1
tinyrainbow: 2.0.0 tinyrainbow: 2.0.0
vite: 7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vite: 7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
vite-node: 3.2.4(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vite-node: 3.2.4(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
why-is-node-running: 2.3.0 why-is-node-running: 2.3.0
optionalDependencies: optionalDependencies:
'@types/debug': 4.1.12 '@types/debug': 4.1.12
'@types/node': 24.10.0 '@types/node': 24.10.0
'@vitest/browser': 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(playwright@1.56.1)(utf-8-validate@6.0.5)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)) '@vitest/browser': 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.0)(typescript@5.9.3))(playwright@1.56.1)(utf-8-validate@6.0.5)(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4)(webdriverio@9.20.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))
'@vitest/ui': 3.2.4(vitest@3.2.4) '@vitest/ui': 3.2.4(vitest@3.2.4)
happy-dom: 20.0.10 happy-dom: 20.0.10
jsdom: 26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) jsdom: 26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)