@photostructure/fs-metadata 0.8.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -2
- package/README.md +5 -0
- package/binding.gyp +12 -5
- package/dist/index.cjs +114 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -4
- package/dist/index.d.mts +30 -4
- package/dist/index.d.ts +30 -4
- package/dist/index.mjs +112 -34
- package/dist/index.mjs.map +1 -1
- package/doc/SECURITY_AUDIT_2025.md +22 -7
- package/package.json +1 -1
- package/prebuilds/darwin-arm64/@photostructure+fs-metadata.glibc.node +0 -0
- package/prebuilds/darwin-x64/@photostructure+fs-metadata.glibc.node +0 -0
- package/prebuilds/linux-arm64/@photostructure+fs-metadata.glibc.node +0 -0
- package/prebuilds/linux-x64/@photostructure+fs-metadata.glibc.node +0 -0
- package/prebuilds/win32-arm64/@photostructure+fs-metadata.glibc.node +0 -0
- package/prebuilds/win32-x64/@photostructure+fs-metadata.glibc.node +0 -0
- package/src/index.ts +4 -0
- package/src/linux/mtab.ts +10 -3
- package/src/options.ts +114 -3
- package/src/remote_info.ts +28 -34
- package/src/types/options.ts +7 -0
- package/src/volume_metadata.ts +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -14,6 +14,19 @@ Fixed for any bug fixes.
|
|
|
14
14
|
Security in case of vulnerabilities.
|
|
15
15
|
-->
|
|
16
16
|
|
|
17
|
+
## 0.9.0 - 2025-12-28
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- New `networkFsTypes` option for configuring network filesystem detection
|
|
22
|
+
- `NetworkFsTypesDefault` and `SkipNetworkVolumesDefault` exports
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- Expanded `SystemFsTypesDefault` with `bpf`, `tracefs`, `nsfs`, `ramfs`, `rpc_pipefs`, `fuse.lxcfs`, `fuse.portal`
|
|
27
|
+
- Expanded `SystemPathPatternsDefault` with macOS metadata paths, kubelet, LXC/LXD, Flatpak paths
|
|
28
|
+
- `isRemoteFsType()` and `extractRemoteInfo()` accept optional `networkFsTypes` parameter
|
|
29
|
+
|
|
17
30
|
## 0.8.1 - 2025-12-28
|
|
18
31
|
|
|
19
32
|
### Changed
|
|
@@ -104,9 +117,9 @@ Security in case of vulnerabilities.
|
|
|
104
117
|
|
|
105
118
|
- `Packaging`: Improved ESM/CJS support with common `__dirname` implementation thanks to `tsup` [shims](https://tsup.egoist.dev/#inject-cjs-and-esm-shims).
|
|
106
119
|
|
|
107
|
-
This change simplifies the implementation and improves inline
|
|
120
|
+
This change simplifies the implementation and improves inline js docs as the exported code and docs have been inlined.
|
|
108
121
|
|
|
109
|
-
- `Packaging`: Re-enabled test coverage assertions (after finding the
|
|
122
|
+
- `Packaging`: Re-enabled test coverage assertions (after finding the magics to get istanbul to see what the tests were exercising)
|
|
110
123
|
|
|
111
124
|
- `Packaging`: Added debuglog tests
|
|
112
125
|
|
package/README.md
CHANGED
|
@@ -48,6 +48,7 @@ console.log(metadata);
|
|
|
48
48
|
|
|
49
49
|
## Documentation
|
|
50
50
|
|
|
51
|
+
- [Security reporting](./SECURITY.md) - How to report security issues
|
|
51
52
|
- [API Reference](https://photostructure.github.io/fs-metadata/modules.html)
|
|
52
53
|
- [Examples](./doc/examples.md) - Common usage patterns and recipes
|
|
53
54
|
- [Gotchas](./doc/gotchas.md) - Platform quirks, timeouts, and troubleshooting
|
|
@@ -59,3 +60,7 @@ console.log(metadata);
|
|
|
59
60
|
- **Timeouts**: Configure [timeout duration](https://photostructure.github.io/fs-metadata/functions/getTimeoutMsDefault.html) for slow devices
|
|
60
61
|
- Set `FS_METADATA_TIMEOUT_MS` environment variable to override the default (5000ms)
|
|
61
62
|
- **System Volumes**: Control [system volume filtering](https://photostructure.github.io/fs-metadata/interfaces/Options.html)
|
|
63
|
+
|
|
64
|
+
## Development
|
|
65
|
+
|
|
66
|
+
Development of this library was assisted by AI coding tools. All changes are human-reviewed and tested.
|
package/binding.gyp
CHANGED
|
@@ -31,11 +31,13 @@
|
|
|
31
31
|
"-lblkid"
|
|
32
32
|
],
|
|
33
33
|
"cflags": [
|
|
34
|
-
"-fPIC"
|
|
34
|
+
"-fPIC",
|
|
35
|
+
"-fstack-protector-strong"
|
|
35
36
|
],
|
|
36
37
|
"cflags_cc": [
|
|
37
38
|
"-fexceptions",
|
|
38
|
-
"-fPIC"
|
|
39
|
+
"-fPIC",
|
|
40
|
+
"-fstack-protector-strong"
|
|
39
41
|
],
|
|
40
42
|
"conditions": [
|
|
41
43
|
[
|
|
@@ -179,14 +181,19 @@
|
|
|
179
181
|
"CLANG_CXX_LANGUAGE_STANDARD": "c++17",
|
|
180
182
|
"GCC_ENABLE_CPP_EXCEPTIONS": "YES",
|
|
181
183
|
"CLANG_CXX_LIBRARY": "libc++",
|
|
182
|
-
"MACOSX_DEPLOYMENT_TARGET": "10.15"
|
|
184
|
+
"MACOSX_DEPLOYMENT_TARGET": "10.15",
|
|
185
|
+
"OTHER_CFLAGS": [
|
|
186
|
+
"-fstack-protector-strong"
|
|
187
|
+
]
|
|
183
188
|
},
|
|
184
189
|
"cflags": [
|
|
185
190
|
"-fexceptions",
|
|
186
|
-
"-fPIC"
|
|
191
|
+
"-fPIC",
|
|
192
|
+
"-fstack-protector-strong"
|
|
187
193
|
],
|
|
188
194
|
"cflags_cc": [
|
|
189
|
-
"-fexceptions"
|
|
195
|
+
"-fexceptions",
|
|
196
|
+
"-fstack-protector-strong"
|
|
190
197
|
],
|
|
191
198
|
"link_settings": {
|
|
192
199
|
"libraries": [
|
package/dist/index.cjs
CHANGED
|
@@ -32,7 +32,9 @@ var index_exports = {};
|
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
IncludeSystemVolumesDefault: () => IncludeSystemVolumesDefault,
|
|
34
34
|
LinuxMountTablePathsDefault: () => LinuxMountTablePathsDefault,
|
|
35
|
+
NetworkFsTypesDefault: () => NetworkFsTypesDefault,
|
|
35
36
|
OptionsDefault: () => OptionsDefault,
|
|
37
|
+
SkipNetworkVolumesDefault: () => SkipNetworkVolumesDefault,
|
|
36
38
|
SystemFsTypesDefault: () => SystemFsTypesDefault,
|
|
37
39
|
SystemPathPatternsDefault: () => SystemPathPatternsDefault,
|
|
38
40
|
VolumeHealthStatuses: () => VolumeHealthStatuses,
|
|
@@ -628,6 +630,7 @@ var SystemPathPatternsDefault = [
|
|
|
628
630
|
"/proc/**",
|
|
629
631
|
"/run",
|
|
630
632
|
"/run/credentials/**",
|
|
633
|
+
"/run/flatpak/**",
|
|
631
634
|
"/run/lock",
|
|
632
635
|
"/run/snapd/**",
|
|
633
636
|
"/run/user/*/doc",
|
|
@@ -657,12 +660,21 @@ var SystemPathPatternsDefault = [
|
|
|
657
660
|
// - Rootless and rootful container storage
|
|
658
661
|
"/run/containers/**",
|
|
659
662
|
"/var/lib/containers/**",
|
|
660
|
-
//
|
|
663
|
+
//
|
|
664
|
+
// Kubernetes: https://kubernetes.io/docs/reference/node/kubelet-files/
|
|
665
|
+
// - kubelet stores pod data, device plugins, and seccomp profiles
|
|
666
|
+
"/var/lib/kubelet/**",
|
|
667
|
+
//
|
|
668
|
+
// LXC/LXD: https://linuxcontainers.org/
|
|
669
|
+
// - Linux container storage and configuration
|
|
670
|
+
"/var/lib/lxc/**",
|
|
671
|
+
"/var/lib/lxd/**",
|
|
672
|
+
// WSL (Windows Subsystem for Linux):
|
|
661
673
|
"/mnt/wslg/distro",
|
|
662
674
|
"/mnt/wslg/doc",
|
|
663
675
|
"/mnt/wslg/versions.txt",
|
|
664
676
|
"/usr/lib/wsl/drivers",
|
|
665
|
-
//
|
|
677
|
+
// macOS system paths:
|
|
666
678
|
"/private/var/vm",
|
|
667
679
|
// macOS swap
|
|
668
680
|
"/System/Volumes/Hardware",
|
|
@@ -672,11 +684,20 @@ var SystemPathPatternsDefault = [
|
|
|
672
684
|
"/System/Volumes/Reserved",
|
|
673
685
|
"/System/Volumes/Update",
|
|
674
686
|
"/System/Volumes/VM",
|
|
675
|
-
"/System/Volumes/xarts"
|
|
687
|
+
"/System/Volumes/xarts",
|
|
688
|
+
// macOS per-volume metadata (Spotlight, FSEvents, versioning, Trash):
|
|
689
|
+
// https://eclecticlight.co/2021/01/28/spotlight-on-search-how-spotlight-works/
|
|
690
|
+
"**/.DocumentRevisions-V100",
|
|
691
|
+
"**/.fseventsd",
|
|
692
|
+
"**/.Spotlight-V100",
|
|
693
|
+
"**/.Trashes"
|
|
676
694
|
];
|
|
677
695
|
var SystemFsTypesDefault = [
|
|
678
696
|
"autofs",
|
|
679
697
|
"binfmt_misc",
|
|
698
|
+
// BPF filesystem for persistent BPF objects
|
|
699
|
+
// https://docs.kernel.org/bpf/
|
|
700
|
+
"bpf",
|
|
680
701
|
"cgroup",
|
|
681
702
|
"cgroup2",
|
|
682
703
|
"configfs",
|
|
@@ -685,24 +706,98 @@ var SystemFsTypesDefault = [
|
|
|
685
706
|
"devtmpfs",
|
|
686
707
|
"efivarfs",
|
|
687
708
|
"fusectl",
|
|
709
|
+
// LXC container filesystem virtualization
|
|
710
|
+
// https://linuxcontainers.org/lxcfs/
|
|
711
|
+
"fuse.lxcfs",
|
|
712
|
+
// XDG Desktop Portal for Flatpak sandboxed app file access
|
|
713
|
+
// https://flatpak.github.io/xdg-desktop-portal/
|
|
714
|
+
"fuse.portal",
|
|
688
715
|
"fuse.snapfuse",
|
|
689
716
|
"hugetlbfs",
|
|
690
717
|
"mqueue",
|
|
691
718
|
"none",
|
|
719
|
+
// Linux namespace filesystem (internal kernel use)
|
|
720
|
+
// https://man7.org/linux/man-pages/man7/namespaces.7.html
|
|
721
|
+
"nsfs",
|
|
692
722
|
"proc",
|
|
693
723
|
"pstore",
|
|
724
|
+
// RAM-based filesystem (predecessor to tmpfs)
|
|
725
|
+
// https://www.kernel.org/doc/html/latest/filesystems/ramfs-rootfs-initramfs.html
|
|
726
|
+
"ramfs",
|
|
694
727
|
"rootfs",
|
|
728
|
+
// NFS RPC communication pipe filesystem
|
|
729
|
+
// https://man7.org/linux/man-pages/man8/rpc.gssd.8.html
|
|
730
|
+
"rpc_pipefs",
|
|
695
731
|
"securityfs",
|
|
696
732
|
"snap*",
|
|
697
733
|
"squashfs",
|
|
698
734
|
"sysfs",
|
|
699
|
-
"tmpfs"
|
|
735
|
+
"tmpfs",
|
|
736
|
+
// Kernel function tracing filesystem
|
|
737
|
+
// https://www.kernel.org/doc/html/latest/trace/ftrace.html
|
|
738
|
+
"tracefs"
|
|
700
739
|
];
|
|
701
740
|
var LinuxMountTablePathsDefault = [
|
|
702
741
|
"/proc/self/mounts",
|
|
703
742
|
"/proc/mounts",
|
|
704
743
|
"/etc/mtab"
|
|
705
744
|
];
|
|
745
|
+
var NetworkFsTypesDefault = [
|
|
746
|
+
// Plan 9 filesystem (VM host-guest, also network)
|
|
747
|
+
// https://www.kernel.org/doc/html/latest/filesystems/9p.html
|
|
748
|
+
"9p",
|
|
749
|
+
// Apple Filing Protocol (legacy macOS/netatalk)
|
|
750
|
+
"afp",
|
|
751
|
+
// Andrew File System (distributed) - not to be confused with Apple's APFS
|
|
752
|
+
// https://www.openafs.org/
|
|
753
|
+
"afs",
|
|
754
|
+
// BeeGFS parallel filesystem (HPC)
|
|
755
|
+
// https://www.beegfs.io/
|
|
756
|
+
"beegfs",
|
|
757
|
+
// Ceph distributed filesystem
|
|
758
|
+
// https://docs.ceph.com/
|
|
759
|
+
"ceph",
|
|
760
|
+
// Windows/Samba shares (SMB/CIFS)
|
|
761
|
+
// https://www.samba.org/
|
|
762
|
+
"cifs",
|
|
763
|
+
// FTP filesystem mount
|
|
764
|
+
"ftp",
|
|
765
|
+
// Generic FUSE (often remote, treated conservatively)
|
|
766
|
+
"fuse",
|
|
767
|
+
// rclone cloud storage mount (Google Drive, S3, etc.)
|
|
768
|
+
// https://rclone.org/commands/rclone_mount/
|
|
769
|
+
"fuse.rclone",
|
|
770
|
+
// Amazon S3 FUSE mount
|
|
771
|
+
// https://github.com/s3fs-fuse/s3fs-fuse
|
|
772
|
+
"fuse.s3fs",
|
|
773
|
+
// SSH filesystem
|
|
774
|
+
// https://github.com/libfuse/sshfs
|
|
775
|
+
"fuse.sshfs",
|
|
776
|
+
// Red Hat Global File System (cluster)
|
|
777
|
+
"gfs",
|
|
778
|
+
"gfs2",
|
|
779
|
+
// GlusterFS distributed filesystem
|
|
780
|
+
// https://www.gluster.org/
|
|
781
|
+
"glusterfs",
|
|
782
|
+
// Lustre parallel filesystem (HPC)
|
|
783
|
+
// https://www.lustre.org/
|
|
784
|
+
"lustre",
|
|
785
|
+
// Novell NetWare (legacy)
|
|
786
|
+
"ncpfs",
|
|
787
|
+
"ncp",
|
|
788
|
+
// Network File System
|
|
789
|
+
// https://man7.org/linux/man-pages/man5/nfs.5.html
|
|
790
|
+
"nfs",
|
|
791
|
+
"nfs4",
|
|
792
|
+
// SMB filesystem
|
|
793
|
+
"smb",
|
|
794
|
+
"smbfs",
|
|
795
|
+
// SSH filesystem (non-FUSE variant)
|
|
796
|
+
"sshfs",
|
|
797
|
+
// WebDAV filesystem
|
|
798
|
+
// https://savannah.nongnu.org/projects/davfs2
|
|
799
|
+
"webdav"
|
|
800
|
+
];
|
|
706
801
|
var IncludeSystemVolumesDefault = isWindows;
|
|
707
802
|
var SkipNetworkVolumesDefault = false;
|
|
708
803
|
var OptionsDefault = {
|
|
@@ -711,6 +806,7 @@ var OptionsDefault = {
|
|
|
711
806
|
systemPathPatterns: [...SystemPathPatternsDefault],
|
|
712
807
|
systemFsTypes: [...SystemFsTypesDefault],
|
|
713
808
|
linuxMountTablePaths: [...LinuxMountTablePathsDefault],
|
|
809
|
+
networkFsTypes: [...NetworkFsTypesDefault],
|
|
714
810
|
includeSystemVolumes: IncludeSystemVolumesDefault,
|
|
715
811
|
skipNetworkVolumes: SkipNetworkVolumesDefault
|
|
716
812
|
};
|
|
@@ -835,38 +931,15 @@ function isRemoteInfo(obj) {
|
|
|
835
931
|
const { remoteHost, remoteShare } = obj;
|
|
836
932
|
return isNotBlank(remoteHost) && isNotBlank(remoteShare);
|
|
837
933
|
}
|
|
838
|
-
var NETWORK_FS_TYPE_ARRAY = [
|
|
839
|
-
"9p",
|
|
840
|
-
"afp",
|
|
841
|
-
"afs",
|
|
842
|
-
"beegfs",
|
|
843
|
-
"ceph",
|
|
844
|
-
"cifs",
|
|
845
|
-
"ftp",
|
|
846
|
-
"fuse",
|
|
847
|
-
"gfs2",
|
|
848
|
-
"glusterfs",
|
|
849
|
-
"lustre",
|
|
850
|
-
"ncpfs",
|
|
851
|
-
"nfs",
|
|
852
|
-
"nfs4",
|
|
853
|
-
"smb",
|
|
854
|
-
"smbfs",
|
|
855
|
-
"sshfs",
|
|
856
|
-
"webdav"
|
|
857
|
-
];
|
|
858
|
-
var NETWORK_FS_TYPES = new Set(NETWORK_FS_TYPE_ARRAY);
|
|
859
934
|
var FS_TYPE_ALIASES = /* @__PURE__ */ new Map([
|
|
860
935
|
["nfs1", "nfs"],
|
|
861
936
|
["nfs2", "nfs"],
|
|
862
937
|
["nfs3", "nfs"],
|
|
863
|
-
["nfs4", "nfs4"],
|
|
864
938
|
["fuse.sshfs", "sshfs"],
|
|
865
939
|
["sshfs.fuse", "sshfs"],
|
|
866
940
|
["davfs2", "webdav"],
|
|
867
941
|
["davfs", "webdav"],
|
|
868
942
|
["cifs.smb", "cifs"],
|
|
869
|
-
["smbfs", "cifs"],
|
|
870
943
|
["cephfs", "ceph"],
|
|
871
944
|
["fuse.ceph", "ceph"],
|
|
872
945
|
["fuse.cephfs", "ceph"],
|
|
@@ -877,8 +950,12 @@ function normalizeFsType(fstype) {
|
|
|
877
950
|
const norm = toS(fstype).toLowerCase().replace(/:$/, "");
|
|
878
951
|
return FS_TYPE_ALIASES.get(norm) ?? norm;
|
|
879
952
|
}
|
|
880
|
-
function isRemoteFsType(fstype) {
|
|
881
|
-
|
|
953
|
+
function isRemoteFsType(fstype, networkFsTypes = NetworkFsTypesDefault) {
|
|
954
|
+
if (!isNotBlank(fstype)) return false;
|
|
955
|
+
const normalized = normalizeFsType(fstype);
|
|
956
|
+
return networkFsTypes.some(
|
|
957
|
+
(nft) => nft === normalized || normalized.startsWith(nft + ".")
|
|
958
|
+
);
|
|
882
959
|
}
|
|
883
960
|
function parseURL(s) {
|
|
884
961
|
try {
|
|
@@ -887,7 +964,7 @@ function parseURL(s) {
|
|
|
887
964
|
return;
|
|
888
965
|
}
|
|
889
966
|
}
|
|
890
|
-
function extractRemoteInfo(fsSpec) {
|
|
967
|
+
function extractRemoteInfo(fsSpec, networkFsTypes = NetworkFsTypesDefault) {
|
|
891
968
|
if (fsSpec == null || isBlank(fsSpec)) return;
|
|
892
969
|
if (isWindows) {
|
|
893
970
|
fsSpec = fsSpec.replace(/\\/g, "/");
|
|
@@ -936,7 +1013,7 @@ function extractRemoteInfo(fsSpec) {
|
|
|
936
1013
|
if (parsed != null) {
|
|
937
1014
|
debug("[extractRemoteInfo] parsed URL: %o", parsed);
|
|
938
1015
|
const fstype = normalizeFsType(parsed.protocol);
|
|
939
|
-
if (!isRemoteFsType(fstype)) {
|
|
1016
|
+
if (!isRemoteFsType(fstype, networkFsTypes)) {
|
|
940
1017
|
return {
|
|
941
1018
|
uri: fsSpec,
|
|
942
1019
|
remote: false
|
|
@@ -1089,6 +1166,7 @@ function mountEntryToMountPoint(entry) {
|
|
|
1089
1166
|
};
|
|
1090
1167
|
}
|
|
1091
1168
|
function mountEntryToPartialVolumeMetadata(entry, options = {}) {
|
|
1169
|
+
const networkFsTypes = options.networkFsTypes ?? NetworkFsTypesDefault;
|
|
1092
1170
|
return {
|
|
1093
1171
|
mountPoint: entry.fs_file,
|
|
1094
1172
|
fstype: entry.fs_vfstype,
|
|
@@ -1096,7 +1174,7 @@ function mountEntryToPartialVolumeMetadata(entry, options = {}) {
|
|
|
1096
1174
|
isSystemVolume: isSystemVolume(entry.fs_file, entry.fs_vfstype, options),
|
|
1097
1175
|
remote: false,
|
|
1098
1176
|
// < default to false, but it may be overridden by extractRemoteInfo
|
|
1099
|
-
...extractRemoteInfo(entry.fs_spec)
|
|
1177
|
+
...extractRemoteInfo(entry.fs_spec, networkFsTypes)
|
|
1100
1178
|
};
|
|
1101
1179
|
}
|
|
1102
1180
|
function parseMtab(content) {
|
|
@@ -1348,9 +1426,9 @@ async function _getVolumeMetadata(o, nativeFn2) {
|
|
|
1348
1426
|
debug("[getVolumeMetadata] requesting native metadata");
|
|
1349
1427
|
const metadata = await (await nativeFn2()).getVolumeMetadata(o);
|
|
1350
1428
|
debug("[getVolumeMetadata] native metadata: %o", metadata);
|
|
1351
|
-
const remoteInfo = mtabInfo ?? extractRemoteInfo(metadata.uri) ?? extractRemoteInfo(metadata.mountFrom) ?? (isWindows ? parseUNCPath(o.mountPoint) : void 0);
|
|
1429
|
+
const remoteInfo = mtabInfo ?? extractRemoteInfo(metadata.uri, o.networkFsTypes) ?? extractRemoteInfo(metadata.mountFrom, o.networkFsTypes) ?? (isWindows ? parseUNCPath(o.mountPoint) : void 0);
|
|
1352
1430
|
debug("[getVolumeMetadata] extracted remote info: %o", remoteInfo);
|
|
1353
|
-
remote ||= isRemoteFsType(metadata.fstype) || (remoteInfo?.remote ?? metadata.remote ?? false);
|
|
1431
|
+
remote ||= isRemoteFsType(metadata.fstype, o.networkFsTypes) || (remoteInfo?.remote ?? metadata.remote ?? false);
|
|
1354
1432
|
debug("[getVolumeMetadata] assembling: %o", {
|
|
1355
1433
|
status,
|
|
1356
1434
|
mtabInfo,
|
|
@@ -1478,7 +1556,9 @@ function setHidden(pathname, hidden, method = "auto") {
|
|
|
1478
1556
|
0 && (module.exports = {
|
|
1479
1557
|
IncludeSystemVolumesDefault,
|
|
1480
1558
|
LinuxMountTablePathsDefault,
|
|
1559
|
+
NetworkFsTypesDefault,
|
|
1481
1560
|
OptionsDefault,
|
|
1561
|
+
SkipNetworkVolumesDefault,
|
|
1482
1562
|
SystemFsTypesDefault,
|
|
1483
1563
|
SystemPathPatternsDefault,
|
|
1484
1564
|
VolumeHealthStatuses,
|