| 
									
										
										
										
											2025-05-31 17:41:56 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-06-22 10:53:04 +03:00
										 |  |  |   description = "Trilium Notes (experimental flake)"; | 
					
						
							| 
									
										
										
										
											2025-05-31 17:41:56 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |   inputs = { | 
					
						
							| 
									
										
										
										
											2025-07-07 14:28:50 +03:00
										 |  |  |     nixpkgs.url = "github:nixos/nixpkgs/master"; | 
					
						
							| 
									
										
										
										
											2025-05-31 18:08:06 +03:00
										 |  |  |     flake-utils.url = "github:numtide/flake-utils"; | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |     pnpm2nix = { | 
					
						
							|  |  |  |       url = "github:FliegendeWurst/pnpm2nix-nzbr"; | 
					
						
							|  |  |  |       inputs.nixpkgs.follows = "nixpkgs"; | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2025-05-31 17:41:56 +03:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-31 18:53:07 +02:00
										 |  |  |   outputs = | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       self, | 
					
						
							|  |  |  |       nixpkgs, | 
					
						
							|  |  |  |       flake-utils, | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |       pnpm2nix, | 
					
						
							| 
									
										
										
										
											2025-05-31 18:53:07 +02:00
										 |  |  |     }: | 
					
						
							|  |  |  |     flake-utils.lib.eachDefaultSystem ( | 
					
						
							|  |  |  |       system: | 
					
						
							| 
									
										
										
										
											2025-05-31 18:08:06 +03:00
										 |  |  |       let | 
					
						
							|  |  |  |         pkgs = import nixpkgs { inherit system; }; | 
					
						
							| 
									
										
										
										
											2025-06-15 23:32:02 +02:00
										 |  |  |         electron = pkgs."electron_${lib.versions.major packageJsonDesktop.devDependencies.electron}"; | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |         nodejs = pkgs.nodejs_22; | 
					
						
							| 
									
										
										
										
											2025-09-10 09:30:26 +02:00
										 |  |  |         # pnpm creates an overly long PATH env variable for child processes. | 
					
						
							|  |  |  |         # This patch deduplicates entries in PATH, which results in an equivalent but shorter entry. | 
					
						
							|  |  |  |         # https://github.com/pnpm/pnpm/issues/6106 | 
					
						
							|  |  |  |         # https://github.com/pnpm/pnpm/issues/8552 | 
					
						
							|  |  |  |         pnpm = (pkgs.pnpm_10.overrideAttrs (prev: { | 
					
						
							|  |  |  |           postInstall = prev.postInstall + ''
 | 
					
						
							|  |  |  |             patch $out/libexec/pnpm/dist/pnpm.cjs ${./patches/pnpm-PATH-reduction.patch} | 
					
						
							|  |  |  |           '';
 | 
					
						
							|  |  |  |         })); | 
					
						
							| 
									
										
										
										
											2025-05-31 18:53:07 +02:00
										 |  |  |         inherit (pkgs) | 
					
						
							|  |  |  |           copyDesktopItems | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |           darwin | 
					
						
							| 
									
										
										
										
											2025-05-31 18:53:07 +02:00
										 |  |  |           lib | 
					
						
							|  |  |  |           makeBinaryWrapper | 
					
						
							|  |  |  |           makeDesktopItem | 
					
						
							| 
									
										
										
										
											2025-06-16 08:05:12 +02:00
										 |  |  |           makeShellWrapper | 
					
						
							| 
									
										
										
										
											2025-06-03 17:30:36 +02:00
										 |  |  |           moreutils | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |           removeReferencesTo | 
					
						
							| 
									
										
										
										
											2025-05-31 18:53:07 +02:00
										 |  |  |           stdenv | 
					
						
							|  |  |  |           wrapGAppsHook3 | 
					
						
							| 
									
										
										
										
											2025-05-31 21:26:19 +03:00
										 |  |  |           xcodebuild | 
					
						
							| 
									
										
										
										
											2025-09-04 12:12:23 +03:00
										 |  |  |           which | 
					
						
							| 
									
										
										
										
											2025-05-31 18:53:07 +02:00
										 |  |  |           ; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |         fullCleanSourceFilter = | 
					
						
							|  |  |  |           name: type: | 
					
						
							|  |  |  |           (lib.cleanSourceFilter name type) | 
					
						
							| 
									
										
										
										
											2025-06-15 23:32:02 +02:00
										 |  |  |           && ( | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |             let | 
					
						
							|  |  |  |               baseName = baseNameOf (toString name); | 
					
						
							|  |  |  |             in | 
					
						
							|  |  |  |             # No need to copy the flake. | 
					
						
							| 
									
										
										
										
											2025-09-10 09:30:26 +02:00
										 |  |  |             # No need to copy local copy of node_modules. | 
					
						
							|  |  |  |             baseName != "flake.nix" && baseName != "flake.lock" && baseName != "node_modules" | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |           ); | 
					
						
							|  |  |  |         fullCleanSource = | 
					
						
							|  |  |  |           src: | 
					
						
							|  |  |  |           lib.cleanSourceWith { | 
					
						
							|  |  |  |             filter = fullCleanSourceFilter; | 
					
						
							|  |  |  |             src = src; | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         packageJson = builtins.fromJSON (builtins.readFile ./package.json); | 
					
						
							| 
									
										
										
										
											2025-06-15 23:32:02 +02:00
										 |  |  |         packageJsonDesktop = builtins.fromJSON (builtins.readFile ./apps/desktop/package.json); | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         makeApp = | 
					
						
							|  |  |  |           { | 
					
						
							|  |  |  |             app, | 
					
						
							|  |  |  |             buildTask, | 
					
						
							|  |  |  |             mainProgram, | 
					
						
							|  |  |  |             installCommands, | 
					
						
							|  |  |  |             preBuildCommands ? "", | 
					
						
							|  |  |  |           }: | 
					
						
							|  |  |  |           pnpm2nix.packages.${system}.mkPnpmPackage rec { | 
					
						
							|  |  |  |             pname = "triliumnext-${app}"; | 
					
						
							|  |  |  |             version = packageJson.version + (lib.optionalString (self ? shortRev) "-${self.shortRev}"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             src = fullCleanSource ./.; | 
					
						
							|  |  |  |             packageJSON = ./package.json; | 
					
						
							|  |  |  |             pnpmLockYaml = ./pnpm-lock.yaml; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             workspace = fullCleanSource ./.; | 
					
						
							|  |  |  |             pnpmWorkspaceYaml = ./pnpm-workspace.yaml; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             inherit nodejs pnpm; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             extraNodeModuleSources = [ | 
					
						
							|  |  |  |               rec { | 
					
						
							|  |  |  |                 name = "patches"; | 
					
						
							|  |  |  |                 value = ./patches; | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             ]; | 
					
						
							| 
									
										
										
										
											2025-05-31 19:24:43 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-03 17:30:36 +02:00
										 |  |  |             # remove pnpm version override | 
					
						
							|  |  |  |             preConfigure = ''
 | 
					
						
							|  |  |  |               cat package.json | grep -v 'packageManager' | sponge package.json | 
					
						
							|  |  |  |             '';
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |             postConfigure = | 
					
						
							|  |  |  |               ''
 | 
					
						
							| 
									
										
										
										
											2025-09-04 12:12:23 +03:00
										 |  |  |                 chmod +x node_modules/electron/install.js | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |                 patchShebangs --build node_modules | 
					
						
							|  |  |  |               '';
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             extraNativeBuildInputs = | 
					
						
							|  |  |  |               [ | 
					
						
							| 
									
										
										
										
											2025-06-03 17:30:36 +02:00
										 |  |  |                 moreutils # sponge | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |                 nodejs.python | 
					
						
							| 
									
										
										
										
											2025-09-04 12:12:23 +03:00
										 |  |  |                 removeReferencesTo                 | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |               ] | 
					
						
							|  |  |  |               ++ lib.optionals (app == "desktop") [ | 
					
						
							|  |  |  |                 copyDesktopItems | 
					
						
							| 
									
										
										
										
											2025-06-16 08:05:12 +02:00
										 |  |  |                 # required for NIXOS_OZONE_WL expansion | 
					
						
							|  |  |  |                 # https://github.com/NixOS/nixpkgs/issues/172583 | 
					
						
							|  |  |  |                 makeShellWrapper | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |                 wrapGAppsHook3 | 
					
						
							| 
									
										
										
										
											2025-09-04 12:12:23 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 # For determining the Electron version to rebuild for: | 
					
						
							|  |  |  |                 which | 
					
						
							|  |  |  |                 electron | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |               ] | 
					
						
							| 
									
										
										
										
											2025-06-16 08:05:12 +02:00
										 |  |  |               ++ lib.optionals (app == "server") [ | 
					
						
							|  |  |  |                 makeBinaryWrapper | 
					
						
							|  |  |  |               ] | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |               ++ lib.optionals stdenv.hostPlatform.isDarwin [ | 
					
						
							|  |  |  |                 xcodebuild | 
					
						
							|  |  |  |                 darwin.cctools | 
					
						
							|  |  |  |               ]; | 
					
						
							|  |  |  |             dontWrapGApps = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             env.ELECTRON_SKIP_BINARY_DOWNLOAD = "1"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             preBuild = ''
 | 
					
						
							|  |  |  |               ${preBuildCommands} | 
					
						
							|  |  |  |             '';
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-04 12:12:23 +03:00
										 |  |  |             scriptFull = "pnpm run ${buildTask}"; | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             installPhase = ''
 | 
					
						
							|  |  |  |               runHook preInstall | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               ${installCommands} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               runHook postInstall | 
					
						
							|  |  |  |             '';
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-10 09:30:26 +02:00
										 |  |  |             # This file is a symlink into /build which is not allowed. | 
					
						
							|  |  |  |             postFixup = ''
 | 
					
						
							|  |  |  |               rm $out/opt/trilium*/node_modules/better-sqlite3/node_modules/.bin/prebuild-install || true | 
					
						
							|  |  |  |             '';
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |             components = [ | 
					
						
							|  |  |  |               "packages/ckeditor5" | 
					
						
							|  |  |  |               "packages/ckeditor5-admonition" | 
					
						
							|  |  |  |               "packages/ckeditor5-footnotes" | 
					
						
							|  |  |  |               "packages/ckeditor5-keyboard-marker" | 
					
						
							|  |  |  |               "packages/ckeditor5-math" | 
					
						
							|  |  |  |               "packages/ckeditor5-mermaid" | 
					
						
							|  |  |  |               "packages/codemirror" | 
					
						
							|  |  |  |               "packages/commons" | 
					
						
							|  |  |  |               "packages/express-partial-content" | 
					
						
							|  |  |  |               "packages/highlightjs" | 
					
						
							|  |  |  |               "packages/turndown-plugin-gfm" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               "apps/client" | 
					
						
							|  |  |  |               "apps/db-compare" | 
					
						
							|  |  |  |               "apps/desktop" | 
					
						
							|  |  |  |               "apps/dump-db" | 
					
						
							|  |  |  |               "apps/edit-docs" | 
					
						
							|  |  |  |               "apps/server" | 
					
						
							|  |  |  |               "apps/server-e2e" | 
					
						
							|  |  |  |             ]; | 
					
						
							| 
									
										
										
										
											2025-05-31 19:24:43 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |             desktopItems = lib.optionals (app == "desktop") [ | 
					
						
							|  |  |  |               (makeDesktopItem { | 
					
						
							| 
									
										
										
										
											2025-06-22 10:53:04 +03:00
										 |  |  |                 name = "Trilium Notes"; | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |                 exec = meta.mainProgram; | 
					
						
							|  |  |  |                 icon = "trilium"; | 
					
						
							|  |  |  |                 comment = meta.description; | 
					
						
							| 
									
										
										
										
											2025-06-22 10:53:04 +03:00
										 |  |  |                 desktopName = "Trilium Notes"; | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |                 categories = [ "Office" ]; | 
					
						
							| 
									
										
										
										
											2025-06-22 10:53:04 +03:00
										 |  |  |                 startupWMClass = "Trilium Notes"; | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |               }) | 
					
						
							|  |  |  |             ]; | 
					
						
							| 
									
										
										
										
											2025-05-31 18:53:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |             meta = { | 
					
						
							| 
									
										
										
										
											2025-06-22 10:53:04 +03:00
										 |  |  |               description = "Trilium: ${app}"; | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |               inherit mainProgram; | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  |           }; | 
					
						
							| 
									
										
										
										
											2025-05-31 17:41:56 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |         desktop = makeApp { | 
					
						
							|  |  |  |           app = "desktop"; | 
					
						
							| 
									
										
										
										
											2025-09-10 09:30:26 +02:00
										 |  |  |           # pnpm throws an error at the end of `pnpm postinstall`, but it doesn't seem to matter: | 
					
						
							|  |  |  |           # ENOENT: no such file or directory, lstat | 
					
						
							|  |  |  |           # '/build/source/apps/desktop/node_modules/better-sqlite3/build/node_gyp_bins' | 
					
						
							|  |  |  |           preBuildCommands = ''
 | 
					
						
							|  |  |  |             export npm_config_nodedir=${electron.headers} | 
					
						
							| 
									
										
										
										
											2025-10-07 18:27:13 +03:00
										 |  |  |             pnpm postinstall | 
					
						
							| 
									
										
										
										
											2025-09-10 09:30:26 +02:00
										 |  |  |           '';
 | 
					
						
							| 
									
										
										
										
											2025-09-04 12:12:23 +03:00
										 |  |  |           buildTask = "desktop:build"; | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |           mainProgram = "trilium"; | 
					
						
							|  |  |  |           installCommands = ''
 | 
					
						
							| 
									
										
										
										
											2025-09-04 12:12:23 +03:00
										 |  |  |             #remove-references-to -t ${electron.headers} apps/desktop/dist/node_modules/better-sqlite3/build/config.gypi | 
					
						
							|  |  |  |             #remove-references-to -t ${nodejs.python} apps/desktop/dist/node_modules/better-sqlite3/build/config.gypi | 
					
						
							| 
									
										
										
										
											2025-05-31 18:53:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-31 19:15:46 +02:00
										 |  |  |             mkdir -p $out/{bin,share/icons/hicolor/512x512/apps,opt/trilium} | 
					
						
							| 
									
										
										
										
											2025-05-31 18:53:07 +02:00
										 |  |  |             cp --archive apps/desktop/dist/* $out/opt/trilium
 | 
					
						
							| 
									
										
										
										
											2025-05-31 19:15:46 +02:00
										 |  |  |             cp apps/client/src/assets/icon.png $out/share/icons/hicolor/512x512/apps/trilium.png | 
					
						
							| 
									
										
										
										
											2025-06-16 08:05:12 +02:00
										 |  |  |             makeShellWrapper ${lib.getExe electron} $out/bin/trilium \ | 
					
						
							| 
									
										
										
										
											2025-05-31 18:53:07 +02:00
										 |  |  |               "''${gappsWrapperArgs[@]}" \ | 
					
						
							| 
									
										
										
										
											2025-06-16 08:05:12 +02:00
										 |  |  |               --add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--ozone-platform-hint=auto --enable-features=WaylandWindowDecorations --enable-wayland-ime=true}}" \
 | 
					
						
							| 
									
										
										
										
											2025-05-31 18:53:07 +02:00
										 |  |  |               --set-default ELECTRON_IS_DEV 0 \ | 
					
						
							| 
									
										
										
										
											2025-06-16 08:08:22 +02:00
										 |  |  |               --set TRILIUM_RESOURCE_DIR $out/opt/trilium \ | 
					
						
							| 
									
										
										
										
											2025-05-31 18:53:07 +02:00
										 |  |  |               --add-flags $out/opt/trilium/main.cjs | 
					
						
							| 
									
										
										
										
											2025-05-31 18:08:06 +03:00
										 |  |  |           '';
 | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         server = makeApp { | 
					
						
							|  |  |  |           app = "server"; | 
					
						
							| 
									
										
										
										
											2025-09-10 09:30:26 +02:00
										 |  |  |           # pnpm throws an error at the end of `pnpm rebuild`, but it doesn't seem to matter: | 
					
						
							|  |  |  |           # ERR_PNPM_MISSING_HOISTED_LOCATIONS | 
					
						
							|  |  |  |           # vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(less@4.1.3)(lightningcss@1.30.1) | 
					
						
							|  |  |  |           # (sass-embedded@1.91.0)(sass@1.91.0)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1) | 
					
						
							|  |  |  |           # is not found in hoistedLocations inside node_modules/.modules.yaml | 
					
						
							|  |  |  |           preBuildCommands = ''
 | 
					
						
							|  |  |  |             pushd apps/server | 
					
						
							|  |  |  |             pnpm rebuild || true | 
					
						
							|  |  |  |             popd | 
					
						
							|  |  |  |           '';
 | 
					
						
							| 
									
										
										
										
											2025-09-04 12:12:23 +03:00
										 |  |  |           buildTask = "server:build"; | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |           mainProgram = "trilium-server"; | 
					
						
							|  |  |  |           installCommands = ''
 | 
					
						
							| 
									
										
										
										
											2025-09-04 12:12:23 +03:00
										 |  |  |             #remove-references-to -t ${nodejs.python} apps/server/dist/node_modules/better-sqlite3/build/config.gypi | 
					
						
							|  |  |  |             #remove-references-to -t ${pnpm} apps/server/dist/node_modules/better-sqlite3/build/config.gypi | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-02 21:01:57 +02:00
										 |  |  |             pushd apps/server/dist | 
					
						
							|  |  |  |             rm -rf node_modules/better-sqlite3/build/Release/obj \ | 
					
						
							|  |  |  |                    node_modules/better-sqlite3/build/Release/obj.target \ | 
					
						
							|  |  |  |                    node_modules/better-sqlite3/build/Release/sqlite3.a \ | 
					
						
							|  |  |  |                    node_modules/better-sqlite3/build/{Makefile,better_sqlite3.target.mk,test_extension.target.mk,binding.Makefile} \ | 
					
						
							|  |  |  |                    node_modules/better-sqlite3/deps/sqlite3 | 
					
						
							|  |  |  |             popd | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |             mkdir -p $out/{bin,opt/trilium-server} | 
					
						
							|  |  |  |             cp --archive apps/server/dist/* $out/opt/trilium-server
 | 
					
						
							|  |  |  |             makeWrapper ${lib.getExe nodejs} $out/bin/trilium-server \ | 
					
						
							|  |  |  |               --add-flags $out/opt/trilium-server/main.cjs | 
					
						
							|  |  |  |           '';
 | 
					
						
							|  |  |  |         }; | 
					
						
							| 
									
										
										
										
											2025-05-31 18:53:07 +02:00
										 |  |  |       in | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2025-06-02 17:55:43 +02:00
										 |  |  |         packages.desktop = desktop; | 
					
						
							|  |  |  |         packages.server = server; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-31 18:53:07 +02:00
										 |  |  |         packages.default = desktop; | 
					
						
							| 
									
										
										
										
											2025-05-31 18:08:06 +03:00
										 |  |  |       } | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2025-05-31 17:41:56 +03:00
										 |  |  | } |