diff --git a/README.md b/README.md index 05661ed4..889ea8b8 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,7 @@ made in Norway 🇳🇴 * [periodic rescan](#periodic-rescan) - filesystem monitoring * [upload rules](#upload-rules) - set upload rules using volflags * [compress uploads](#compress-uploads) - files can be autocompressed on upload + * [chmod and chown](#chmod-and-chown) - per-volume filesystem-permissions and ownership * [other flags](#other-flags) * [database location](#database-location) - in-volume (`.hist/up2k.db`, default) or somewhere else * [metadata from audio files](#metadata-from-audio-files) - set `-e2t` to index tags on upload @@ -151,6 +152,7 @@ just run **[copyparty-sfx.py](https://github.com/9001/copyparty/releases/latest/ * or install [on arch](#arch-package) ╱ [on NixOS](#nixos-module) ╱ [through nix](#nix-package) * or if you are on android, [install copyparty in termux](#install-on-android) * or maybe you have a [synology nas / dsm](./docs/synology-dsm.md) +* or if you have [uv](https://docs.astral.sh/uv/) installed, run `uv tool run copyparty` * or if your computer is messed up and nothing else works, [try the pyz](#zipapp) * or if your OS is dead, give the [bootable flashdrive / cd-rom](https://a.ocv.me/pub/stuff/edcd001/enterprise-edition/) a spin * or if you don't trust copyparty yet and want to isolate it a little, then... @@ -1649,6 +1651,26 @@ some examples, allows (but does not force) gz compression if client uploads to `/inc?pk` or `/inc?gz` or `/inc?gz=4` +## chmod and chown + +per-volume filesystem-permissions and ownership + +by default: +* all folders are chmod 755 +* files are usually chmod 644 (umask-defined) +* user/group is whatever copyparty is running as + +this can be configured per-volume: +* volflag `chmod_f` sets file permissions; default=`644` (usually) +* volflag `chmod_d` sets directory permissions; default=`755` +* volflag `uid` sets the owner user-id +* volflag `gid` sets the owner group-id + +notes: +* `gid` can only be set to one of the groups which the copyparty process is a member of +* `uid` can only be set if copyparty is running as root (i appreciate your faith) + + ## other flags * `:c,magic` enables filetype detection for nameless uploads, same as `--magic` @@ -2226,6 +2248,7 @@ force-enable features with known issues on your OS/env by setting any of the fo | env-var | what it does | | ------------------------ | ------------ | | `PRTY_FORCE_MP` | force-enable multiprocessing (real multithreading) on MacOS and other broken platforms | +| `PRTY_FORCE_MAGIC` | use [magic](https://pypi.org/project/python-magic/) on Windows (you will segfault) | # packages diff --git a/bin/u2c.py b/bin/u2c.py index 99c426c4..85298730 100755 --- a/bin/u2c.py +++ b/bin/u2c.py @@ -52,6 +52,7 @@ if PY2: sys.dont_write_bytecode = True bytes = str + files_decoder = lambda s: unicode(s, 'utf8') else: from urllib.parse import quote_from_bytes as quote from urllib.parse import unquote_to_bytes as unquote @@ -61,6 +62,7 @@ else: from queue import Queue unicode = str + files_decoder = unicode WTF8 = "replace" if PY2 else "surrogateescape" @@ -1532,7 +1534,7 @@ source file/folder selection uses rsync syntax, meaning that: """) ap.add_argument("url", type=unicode, help="server url, including destination folder") - ap.add_argument("files", type=unicode, nargs="+", help="files and/or folders to process") + ap.add_argument("files", type=files_decoder, nargs="+", help="files and/or folders to process") ap.add_argument("-v", action="store_true", help="verbose") ap.add_argument("-a", metavar="PASSWD", help="password or $filepath") ap.add_argument("-s", action="store_true", help="file-search (disables upload)") diff --git a/contrib/nixos/modules/copyparty.nix b/contrib/nixos/modules/copyparty.nix index cd4fef40..994b2575 100644 --- a/contrib/nixos/modules/copyparty.nix +++ b/contrib/nixos/modules/copyparty.nix @@ -22,7 +22,7 @@ let mkValueString = value: if isList value then - (concatStringsSep ", " (map mkValueString value)) + (concatStringsSep "," (map mkValueString value)) else if isAttrs value then "\n" + (mkAttrsString value) else diff --git a/contrib/package/arch/PKGBUILD b/contrib/package/arch/PKGBUILD index bcfe225e..e3529425 100644 --- a/contrib/package/arch/PKGBUILD +++ b/contrib/package/arch/PKGBUILD @@ -3,7 +3,7 @@ # NOTE: You generally shouldn't use this PKGBUILD on Arch, as it is mainly for testing purposes. Install copyparty using pacman instead. pkgname=copyparty -pkgver="1.18.6" +pkgver="1.18.9" pkgrel=1 pkgdesc="File server with accelerated resumable uploads, dedup, WebDAV, FTP, TFTP, zeroconf, media indexer, thumbnails++" arch=("any") @@ -23,7 +23,7 @@ optdepends=("ffmpeg: thumbnails for videos, images (slower) and audio, music tag ) source=("https://github.com/9001/${pkgname}/releases/download/v${pkgver}/${pkgname}-${pkgver}.tar.gz") backup=("etc/${pkgname}.d/init" ) -sha256sums=("80762d91ac88815e73d0ca2806c6391dcf8ccd521bc402cc312349f3bc8e8b28") +sha256sums=("d5d33b50d6717e52427956beb1687061a6f28b467997506505151e3ae18c58e5") build() { cd "${srcdir}/${pkgname}-${pkgver}/copyparty/web" diff --git a/contrib/package/makedeb-mpr/PKGBUILD b/contrib/package/makedeb-mpr/PKGBUILD new file mode 100644 index 00000000..227fc4cf --- /dev/null +++ b/contrib/package/makedeb-mpr/PKGBUILD @@ -0,0 +1,44 @@ +# Contributor: Beethoven + + +pkgname=copyparty +pkgver=1.18.9 +pkgrel=1 +pkgdesc="File server with accelerated resumable uploads, dedup, WebDAV, FTP, TFTP, zeroconf, media indexer, thumbnails++" +arch=("any") +url="https://github.com/9001/${pkgname}" +license=('MIT') +depends=("bash" "python3" "lsof" "python3-jinja2") +makedepends=("python3-wheel" "python3-setuptools" "python3-build" "python3-installer" "make" "pigz") +optdepends=("ffmpeg: thumbnails for videos, images (slower) and audio, music tags" + "golang-cfssl: generate TLS certificates on startup" + "python3-mutagen: music tags (alternative)" + "python3-pil: thumbnails for images" + "python3-openssl: ftps functionality" + "python3-zmq: send zeromq messages from event-hooks" + "python3-argon2: hashed passwords in config" +) +source=("https://github.com/9001/${pkgname}/releases/download/v${pkgver}/${pkgname}-${pkgver}.tar.gz") +backup=("/etc/${pkgname}.d/init" ) +sha256sums=("d5d33b50d6717e52427956beb1687061a6f28b467997506505151e3ae18c58e5") + +build() { + cd "${srcdir}/${pkgname}-${pkgver}/copyparty/web" + make + + cd "${srcdir}/${pkgname}-${pkgver}" + python -m build --wheel --no-isolation +} + +package() { + cd "${srcdir}/${pkgname}-${pkgver}" + python -m installer --destdir="$pkgdir" dist/*.whl + + install -dm755 "${pkgdir}/etc/${pkgname}.d" + install -Dm755 "bin/prisonparty.sh" "${pkgdir}/usr/bin/prisonparty" + install -Dm644 "contrib/package/makedeb-mpr/${pkgname}.conf" "${pkgdir}/etc/${pkgname}.d/init" + install -Dm644 "contrib/package/makedeb-mpr/${pkgname}.service" "${pkgdir}/usr/lib/systemd/system/${pkgname}.service" + install -Dm644 "contrib/package/makedeb-mpr/prisonparty.service" "${pkgdir}/usr/lib/systemd/system/prisonparty.service" + install -Dm644 "contrib/package/makedeb-mpr/index.md" "${pkgdir}/var/lib/${pkgname}-jail/README.md" + install -Dm644 "LICENSE" "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE" +} diff --git a/contrib/package/makedeb-mpr/copyparty.conf b/contrib/package/makedeb-mpr/copyparty.conf new file mode 100644 index 00000000..1d90d772 --- /dev/null +++ b/contrib/package/makedeb-mpr/copyparty.conf @@ -0,0 +1,7 @@ +## import all *.conf files from the current folder (/etc/copyparty.d) +% ./ + +# add additional .conf files to this folder; +# see example config files for reference: +# https://github.com/9001/copyparty/blob/hovudstraum/docs/example.conf +# https://github.com/9001/copyparty/tree/hovudstraum/docs/copyparty.d diff --git a/contrib/package/makedeb-mpr/copyparty.service b/contrib/package/makedeb-mpr/copyparty.service new file mode 100644 index 00000000..22dac3d6 --- /dev/null +++ b/contrib/package/makedeb-mpr/copyparty.service @@ -0,0 +1,32 @@ +# this will start `/usr/bin/copyparty-sfx.py` +# and read config from `/etc/copyparty.d/*.conf` +# +# you probably want to: +# change "User=cpp" and "/home/cpp/" to another user +# +# unless you add -q to disable logging, you may want to remove the +# following line to allow buffering (slightly better performance): +# Environment=PYTHONUNBUFFERED=x + +[Unit] +Description=copyparty file server + +[Service] +Type=notify +SyslogIdentifier=copyparty +Environment=PYTHONUNBUFFERED=x +WorkingDirectory=/var/lib/copyparty-jail +ExecReload=/bin/kill -s USR1 $MAINPID + +# user to run as + where the TLS certificate is (if any) +User=cpp +Environment=XDG_CONFIG_HOME=/home/cpp/.config + +# stop systemd-tmpfiles-clean.timer from deleting copyparty while it's running +ExecStartPre=+/bin/bash -c 'mkdir -p /run/tmpfiles.d/ && echo "x /tmp/pe-copyparty*" > /run/tmpfiles.d/copyparty.conf' + +# run copyparty +ExecStart=/usr/bin/python3 /usr/bin/copyparty -c /etc/copyparty.d/init + +[Install] +WantedBy=multi-user.target diff --git a/contrib/package/makedeb-mpr/index.md b/contrib/package/makedeb-mpr/index.md new file mode 100644 index 00000000..016c0b0a --- /dev/null +++ b/contrib/package/makedeb-mpr/index.md @@ -0,0 +1,3 @@ +this is `/var/lib/copyparty-jail`, the fallback webroot when copyparty has not yet been configured + +please add some `*.conf` files to `/etc/copyparty.d/` diff --git a/contrib/package/makedeb-mpr/prisonparty.service b/contrib/package/makedeb-mpr/prisonparty.service new file mode 100644 index 00000000..cd35ba99 --- /dev/null +++ b/contrib/package/makedeb-mpr/prisonparty.service @@ -0,0 +1,33 @@ +# this will start `/usr/bin/copyparty-sfx.py` +# in a chroot, preventing accidental access elsewhere, +# and read copyparty config from `/etc/copyparty.d/*.conf` +# +# expose additional filesystem locations to copyparty +# by listing them between the last `cpp` and `--` +# +# `cpp cpp` = user/group to run copyparty as; can be IDs (1000 1000) +# +# unless you add -q to disable logging, you may want to remove the +# following line to allow buffering (slightly better performance): +# Environment=PYTHONUNBUFFERED=x + +[Unit] +Description=copyparty file server + +[Service] +SyslogIdentifier=prisonparty +Environment=PYTHONUNBUFFERED=x +WorkingDirectory=/var/lib/copyparty-jail +ExecReload=/bin/kill -s USR1 $MAINPID + +# stop systemd-tmpfiles-clean.timer from deleting copyparty while it's running +ExecStartPre=+/bin/bash -c 'mkdir -p /run/tmpfiles.d/ && echo "x /tmp/pe-copyparty*" > /run/tmpfiles.d/copyparty.conf' + +# run copyparty +ExecStart=/bin/bash /usr/bin/prisonparty /var/lib/copyparty-jail cpp cpp \ + /etc/copyparty.d \ + -- \ + /usr/bin/python3 /usr/bin/copyparty -c /etc/copyparty.d/init + +[Install] +WantedBy=multi-user.target diff --git a/contrib/package/nix/copyparty/pin.json b/contrib/package/nix/copyparty/pin.json index eae921c7..734dec31 100644 --- a/contrib/package/nix/copyparty/pin.json +++ b/contrib/package/nix/copyparty/pin.json @@ -1,5 +1,5 @@ { - "url": "https://github.com/9001/copyparty/releases/download/v1.18.6/copyparty-sfx.py", - "version": "1.18.6", - "hash": "sha256-No89mzKHHZZH19ws9dqfvQO0pnZw7jKDMGhNa4LOFlY=" + "url": "https://github.com/9001/copyparty/releases/download/v1.18.9/copyparty-sfx.py", + "version": "1.18.9", + "hash": "sha256-R1OVx4f8GERAG80ZcHAIP6HK2TlBbKJZpvnJmJbGPRY=" } \ No newline at end of file diff --git a/copyparty/__main__.py b/copyparty/__main__.py index f6c20b8c..71a06033 100644 --- a/copyparty/__main__.py +++ b/copyparty/__main__.py @@ -53,13 +53,13 @@ from .util import ( PYFTPD_VER, RAM_AVAIL, RAM_TOTAL, + RE_ANSI, SQLITE_VER, UNPLICATIONS, URL_BUG, URL_PRJ, Daemon, align_tab, - ansi_re, b64enc, dedent, has_resource, @@ -167,7 +167,7 @@ def lprint(*a: Any, **ka: Any) -> None: txt: str = " ".join(unicode(x) for x in a) + eol printed.append(txt) if not VT100: - txt = ansi_re.sub("", txt) + txt = RE_ANSI.sub("", txt) print(txt, end="", **ka) @@ -1053,6 +1053,8 @@ def add_upload(ap): ap2.add_argument("--use-fpool", action="store_true", help="force file-handle pooling, even when it might be dangerous (multiprocessing, filesystems lacking sparse-files support, ...)") ap2.add_argument("--chmod-f", metavar="UGO", type=u, default="", help="unix file permissions to use when creating files; default is probably 644 (OS-decided), see --help-chmod. Examples: [\033[32m644\033[0m] = owner-RW + all-R, [\033[32m755\033[0m] = owner-RWX + all-RX, [\033[32m777\033[0m] = full-yolo (volflag=chmod_f)") ap2.add_argument("--chmod-d", metavar="UGO", type=u, default="755", help="unix file permissions to use when creating directories; see --help-chmod. Examples: [\033[32m755\033[0m] = owner-RW + all-R, [\033[32m777\033[0m] = full-yolo (volflag=chmod_d)") + ap2.add_argument("--uid", metavar="N", type=int, default=-1, help="unix user-id to chown new files/folders to; default = -1 = do-not-change (volflag=uid)") + ap2.add_argument("--gid", metavar="N", type=int, default=-1, help="unix group-id to chown new files/folders to; default = -1 = do-not-change (volflag=gid)") ap2.add_argument("--dedup", action="store_true", help="enable symlink-based upload deduplication (volflag=dedup)") ap2.add_argument("--safe-dedup", metavar="N", type=int, default=50, help="how careful to be when deduplicating files; [\033[32m1\033[0m] = just verify the filesize, [\033[32m50\033[0m] = verify file contents have not been altered (volflag=safededup)") ap2.add_argument("--hardlink", action="store_true", help="enable hardlink-based dedup; will fallback on symlinks when that is impossible (across filesystems) (volflag=hardlink)") @@ -1107,7 +1109,7 @@ def add_tls(ap, cert_path): ap2 = ap.add_argument_group('SSL/TLS options') ap2.add_argument("--http-only", action="store_true", help="disable ssl/tls -- force plaintext") ap2.add_argument("--https-only", action="store_true", help="disable plaintext -- force tls") - ap2.add_argument("--cert", metavar="PATH", type=u, default=cert_path, help="path to TLS certificate") + ap2.add_argument("--cert", metavar="PATH", type=u, default=cert_path, help="path to file containing a concatenation of TLS key and certificate chain") ap2.add_argument("--ssl-ver", metavar="LIST", type=u, default="", help="set allowed ssl/tls versions; [\033[32mhelp\033[0m] shows available versions; default is what your python version considers safe") ap2.add_argument("--ciphers", metavar="LIST", type=u, default="", help="set allowed ssl/tls ciphers; [\033[32mhelp\033[0m] shows available ciphers") ap2.add_argument("--ssl-dbg", action="store_true", help="dump some tls info") @@ -1546,6 +1548,7 @@ def add_ui(ap, retry): ap2 = ap.add_argument_group('ui options') ap2.add_argument("--grid", action="store_true", help="show grid/thumbnails by default (volflag=grid)") ap2.add_argument("--gsel", action="store_true", help="select files in grid by ctrl-click (volflag=gsel)") + ap2.add_argument("--localtime", action="store_true", help="default to local timezone instead of UTC") ap2.add_argument("--lang", metavar="LANG", type=u, default="eng", help="language; one of the following: \033[32meng nor chi\033[0m") ap2.add_argument("--theme", metavar="NUM", type=int, default=0, help="default theme to use (0..7)") ap2.add_argument("--themes", metavar="NUM", type=int, default=8, help="number of themes installed") @@ -1555,7 +1558,7 @@ def add_ui(ap, retry): ap2.add_argument("--hsortn", metavar="N", type=int, default=2, help="number of sorting rules to include in media URLs by default (volflag=hsortn)") ap2.add_argument("--see-dots", action="store_true", help="default-enable seeing dotfiles; only takes effect if user has the necessary permissions") ap2.add_argument("--qdel", metavar="LVL", type=int, default=2, help="number of confirmations to show when deleting files (2/1/0)") - ap2.add_argument("--unlist", metavar="REGEX", type=u, default="", help="don't show files matching \033[33mREGEX\033[0m in file list. Purely cosmetic! Does not affect API calls, just the browser. Example: [\033[32m\\.(js|css)$\033[0m] (volflag=unlist)") + ap2.add_argument("--unlist", metavar="REGEX", type=u, default="", help="don't show files/folders matching \033[33mREGEX\033[0m in file list. WARNING: Purely cosmetic! Does not affect API calls, just the browser. Example: [\033[32m\\.(js|css)$\033[0m] (volflag=unlist)") ap2.add_argument("--favico", metavar="TXT", type=u, default="c 000 none" if retry else "🎉 000 none", help="\033[33mfavicon-text\033[0m [ \033[33mforeground\033[0m [ \033[33mbackground\033[0m ] ], set blank to disable") ap2.add_argument("--ext-th", metavar="E=VP", type=u, action="append", help="use thumbnail-image \033[33mVP\033[0m for file-extension \033[33mE\033[0m, example: [\033[32mexe=/.res/exe.png\033[0m] (volflag=ext_th)") ap2.add_argument("--mpmc", metavar="URL", type=u, default="", help="change the mediaplayer-toggle mouse cursor; URL to a folder with {2..5}.png inside (or disable with [\033[32m.\033[0m])") diff --git a/copyparty/__version__.py b/copyparty/__version__.py index 3cbb3b4a..a82053fb 100644 --- a/copyparty/__version__.py +++ b/copyparty/__version__.py @@ -1,8 +1,8 @@ # coding: utf-8 -VERSION = (1, 18, 6) +VERSION = (1, 18, 9) CODENAME = "logtail" -BUILD_DT = (2025, 7, 28) +BUILD_DT = (2025, 8, 1) S_VERSION = ".".join(map(str, VERSION)) S_BUILD_DT = "{0:04d}-{1:02d}-{2:02d}".format(*BUILD_DT) diff --git a/copyparty/authsrv.py b/copyparty/authsrv.py index bdc65640..01fad895 100644 --- a/copyparty/authsrv.py +++ b/copyparty/authsrv.py @@ -33,6 +33,7 @@ from .util import ( afsenc, get_df, humansize, + json_hesc, min_ex, odfusion, read_utf8, @@ -70,6 +71,25 @@ if PY2: LEELOO_DALLAS = "leeloo_dallas" +## +## you might be curious what Leeloo Dallas is doing here, so let me explain: +## +## certain daemonic tasks, namely: +## * deletion of expired files, running on a timer +## * deletion of sidecar files, initiated by plugins +## need to skip the usual permission-checks to do their thing, +## so we let Leeloo handle these +## +## and also, the smb-server has really shitty support for user-accounts +## so one popular way to avoid issues is by running copyparty without users; +## this makes all smb-clients identify as LD to gain unrestricted access +## +## Leeloo, being a fictional character from The Fifth Element, +## obviously does not exist and will never be able to access any copyparty +## instances from the outside (the username is rejected at every entrypoint) +## +## thanks for coming to my ted talk + SEE_LOG = "see log for details" SEESLOG = " (see serverlog for details)" @@ -121,6 +141,8 @@ class Lim(object): self.reg: Optional[dict[str, dict[str, Any]]] = None # up2k registry self.chmod_d = 0o755 + self.uid = self.gid = -1 + self.chown = False self.nups: dict[str, list[float]] = {} # num tracker self.bups: dict[str, list[tuple[float, int]]] = {} # byte tracker list @@ -283,6 +305,8 @@ class Lim(object): # no branches yet; make one sub = os.path.join(path, "0") bos.mkdir(sub, self.chmod_d) + if self.chown: + os.chown(sub, self.uid, self.gid) else: # try newest branch only sub = os.path.join(path, str(dirs[-1])) @@ -298,6 +322,8 @@ class Lim(object): # make a branch sub = os.path.join(path, str(dirs[-1] + 1)) bos.mkdir(sub, self.chmod_d) + if self.chown: + os.chown(sub, self.uid, self.gid) ret = self.dive(sub, lvs - 1) if ret is None: raise Pebkac(500, "rotation bug") @@ -2162,7 +2188,7 @@ class AuthSrv(object): if vf not in vol.flags: vol.flags[vf] = getattr(self.args, ga) - zs = "forget_ip nrand tail_who u2abort u2ow ups_who zip_who" + zs = "forget_ip gid nrand tail_who u2abort u2ow uid ups_who zip_who" for k in zs.split(): if k in vol.flags: vol.flags[k] = int(vol.flags[k]) @@ -2199,8 +2225,17 @@ class AuthSrv(object): if (is_d and zi != 0o755) or not is_d: free_umask = True + vol.flags.pop("chown", None) + if vol.flags["uid"] != -1 or vol.flags["gid"] != -1: + vol.flags["chown"] = True + vol.flags.pop("fperms", None) + if "chown" in vol.flags or vol.flags.get("chmod_f"): + vol.flags["fperms"] = True if vol.lim: vol.lim.chmod_d = vol.flags["chmod_d"] + vol.lim.chown = "chown" in vol.flags + vol.lim.uid = vol.flags["uid"] + vol.lim.gid = vol.flags["gid"] if vol.flags.get("og"): self.args.uqe = True @@ -2740,6 +2775,7 @@ class AuthSrv(object): "dth3x": vf["th3x"], "dvol": self.args.au_vol, "idxh": int(self.args.ih), + "dutc": not self.args.localtime, "themes": self.args.themes, "turbolvl": self.args.turbo, "nosubtle": self.args.nosubtle, @@ -2751,7 +2787,7 @@ class AuthSrv(object): "lifetime": vn.js_ls["lifetime"], "u2sort": self.args.u2sort, } - vn.js_htm = json.dumps(js_htm) + vn.js_htm = json_hesc(json.dumps(js_htm)) vols = list(vfs.all_nodes.values()) if enshare: @@ -3422,7 +3458,7 @@ def expand_config_file( ipath += " -> " + fp ret.append("#\033[36m opening cfg file{}\033[0m".format(ipath)) - cfg_lines = read_utf8(log, fp, True).split("\n") + cfg_lines = read_utf8(log, fp, True).replace("\t", " ").split("\n") if True: # diff-golf for oln in [x.rstrip() for x in cfg_lines]: ln = oln.split(" #")[0].strip() diff --git a/copyparty/bos/bos.py b/copyparty/bos/bos.py index 3d98d0df..6c876e04 100644 --- a/copyparty/bos/bos.py +++ b/copyparty/bos/bos.py @@ -9,8 +9,11 @@ from . import path as path if True: # pylint: disable=using-constant-test from typing import Any, Optional -_ = (path,) -__all__ = ["path"] +MKD_755 = {"chmod_d": 0o755} +MKD_700 = {"chmod_d": 0o700} + +_ = (path, MKD_755, MKD_700) +__all__ = ["path", "MKD_755", "MKD_700"] # grep -hRiE '(^|[^a-zA-Z_\.-])os\.' . | gsed -r 's/ /\n/g;s/\(/(\n/g' | grep -hRiE '(^|[^a-zA-Z_\.-])os\.' | sort | uniq -c # printf 'os\.(%s)' "$(grep ^def bos/__init__.py | gsed -r 's/^def //;s/\(.*//' | tr '\n' '|' | gsed -r 's/.$//')" @@ -20,11 +23,15 @@ def chmod(p: str, mode: int) -> None: return os.chmod(fsenc(p), mode) +def chown(p: str, uid: int, gid: int) -> None: + return os.chown(fsenc(p), uid, gid) + + def listdir(p: str = ".") -> list[str]: return [fsdec(x) for x in os.listdir(fsenc(p))] -def makedirs(name: str, mode: int = 0o755, exist_ok: bool = True) -> bool: +def makedirs(name: str, vf: dict[str, Any] = MKD_755, exist_ok: bool = True) -> bool: # os.makedirs does 777 for all but leaf; this does mode on all todo = [] bname = fsenc(name) @@ -37,9 +44,13 @@ def makedirs(name: str, mode: int = 0o755, exist_ok: bool = True) -> bool: if not exist_ok: os.mkdir(bname) # to throw return False + mode = vf["chmod_d"] + chown = "chown" in vf for zb in todo[::-1]: try: os.mkdir(zb, mode) + if chown: + os.chown(zb, vf["uid"], vf["gid"]) except: if os.path.isdir(zb): continue diff --git a/copyparty/cfg.py b/copyparty/cfg.py index cee8214b..2f75ab28 100644 --- a/copyparty/cfg.py +++ b/copyparty/cfg.py @@ -114,6 +114,8 @@ def vf_vmap() -> dict[str, str]: "unlist", "u2abort", "u2ts", + "uid", + "gid", "ups_who", "zip_who", "zipmaxn", @@ -175,6 +177,8 @@ flagcats = { "nodupe": "rejects existing files (instead of linking/cloning them)", "chmod_d=755": "unix-permission for new dirs/folders", "chmod_f=644": "unix-permission for new files", + "uid=573": "change owner of new files/folders to unix-user 573", + "gid=999": "change owner of new files/folders to unix-group 999", "sparse": "force use of sparse files, mainly for s3-backed storage", "nosparse": "deny use of sparse files, mainly for slow storage", "daw": "enable full WebDAV write support (dangerous);\nPUT-operations will now \033[1;31mOVERWRITE\033[0;35m existing files", diff --git a/copyparty/ftpd.py b/copyparty/ftpd.py index c464450e..2f45c3f4 100644 --- a/copyparty/ftpd.py +++ b/copyparty/ftpd.py @@ -31,6 +31,7 @@ from .util import ( relchk, runhook, sanitize_fn, + set_fperms, vjoin, wunlink, ) @@ -262,8 +263,8 @@ class FtpFs(AbstractedFS): wunlink(self.log, ap, VF_CAREFUL) ret = open(fsenc(ap), mode, self.args.iobuf) - if w and "chmod_f" in vfs.flags: - os.fchmod(ret.fileno(), vfs.flags["chmod_f"]) + if w and "fperms" in vfs.flags: + set_fperms(ret, vfs.flags) return ret @@ -297,8 +298,7 @@ class FtpFs(AbstractedFS): def mkdir(self, path: str) -> None: ap, vfs, _ = self.rv2a(path, w=True) - chmod = vfs.flags["chmod_d"] - bos.makedirs(ap, chmod) # filezilla expects this + bos.makedirs(ap, vf=vfs.flags) # filezilla expects this def listdir(self, path: str) -> list[str]: vpath = join(self.cwd, path) diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index 8bb12870..bea4ce43 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -33,7 +33,7 @@ except: from .__init__ import ANYWIN, PY2, RES, TYPE_CHECKING, EnvParams, unicode from .__version__ import S_VERSION -from .authsrv import VFS # typechk +from .authsrv import LEELOO_DALLAS, VFS # typechk from .bos import bos from .star import StreamTar from .stolen.qrcodegen import QrCode, qr2svg @@ -79,8 +79,10 @@ from .util import ( hidedir, html_bescape, html_escape, + html_sh_esc, humansize, ipnorm, + json_hesc, justcopy, load_resource, loadpy, @@ -103,7 +105,9 @@ from .util import ( sanitize_vpath, sendfile_kern, sendfile_py, + set_fperms, stat_resource, + str_anchor, ub64dec, ub64enc, ujoin, @@ -622,6 +626,9 @@ class HttpCli(object): ) or self.args.idp_h_key in self.headers if trusted_key and trusted_xff: + if idp_usr.lower() == LEELOO_DALLAS: + self.loud_reply("send her back", status=403) + return False self.asrv.idp_checkin(self.conn.hsrv.broker, idp_usr, idp_grp) else: if not trusted_key: @@ -905,7 +912,7 @@ class HttpCli(object): if status == 304: self.out_headers.pop("Content-Length", None) self.out_headers.pop("Content-Type", None) - self.out_headerlist.clear() + self.out_headerlist[:] = [] if self.k304(): self.keepalive = False else: @@ -1110,15 +1117,18 @@ class HttpCli(object): else: return True + host = self.host.lower() + if host.startswith("["): + if "]:" in host: + host = host.split("]:")[0] + "]" + else: + host = host.split(":")[0] + oh = self.out_headers origin = origin.lower() - good_origins = self.args.acao + [ - "%s://%s" - % ( - "https" if self.is_https else "http", - self.host.lower().split(":")[0], - ) - ] + proto = "https" if self.is_https else "http" + good_origins = self.args.acao + ["%s://%s" % (proto, host)] + if "pw" in ih or re.sub(r"(:[0-9]{1,5})?/?$", "", origin) in good_origins: good_origin = True bad_hdrs = ("",) @@ -2083,7 +2093,7 @@ class HttpCli(object): fdir, fn = os.path.split(fdir) rem, _ = vsplit(rem) - bos.makedirs(fdir, vfs.flags["chmod_d"]) + bos.makedirs(fdir, vf=vfs.flags) open_ka: dict[str, Any] = {"fun": open} open_a = ["wb", self.args.iobuf] @@ -2141,9 +2151,7 @@ class HttpCli(object): if nameless: fn = vfs.flags["put_name2"].format(now=time.time(), cip=self.dip()) - params = {"suffix": suffix, "fdir": fdir} - if "chmod_f" in vfs.flags: - params["chmod"] = vfs.flags["chmod_f"] + params = {"suffix": suffix, "fdir": fdir, "vf": vfs.flags} if self.args.nw: params = {} fn = os.devnull @@ -2192,7 +2200,7 @@ class HttpCli(object): if self.args.nw: fn = os.devnull else: - bos.makedirs(fdir, vfs.flags["chmod_d"]) + bos.makedirs(fdir, vf=vfs.flags) path = os.path.join(fdir, fn) if not nameless: self.vpath = vjoin(self.vpath, fn) @@ -2324,7 +2332,7 @@ class HttpCli(object): if self.args.hook_v: log_reloc(self.log, hr["reloc"], x, path, vp, fn, vfs, rem) fdir, self.vpath, fn, (vfs, rem) = x - bos.makedirs(fdir, vfs.flags["chmod_d"]) + bos.makedirs(fdir, vf=vfs.flags) path2 = os.path.join(fdir, fn) atomic_move(self.log, path, path2, vfs.flags) path = path2 @@ -2610,7 +2618,7 @@ class HttpCli(object): dst = vfs.canonical(rem) try: if not bos.path.isdir(dst): - bos.makedirs(dst, vfs.flags["chmod_d"]) + bos.makedirs(dst, vf=vfs.flags) except OSError as ex: self.log("makedirs failed %r" % (dst,)) if not bos.path.isdir(dst): @@ -2933,7 +2941,7 @@ class HttpCli(object): msg = "new password OK" redir = (self.args.SRS + "?h") if ok else "" - h2 = 'ack' + h2 = 'continue' html = self.j2s("msg", h1=msg, h2=h2, redir=redir) self.reply(html.encode("utf-8")) return True @@ -2962,7 +2970,8 @@ class HttpCli(object): dst += "_=1#" + html_escape(uhash, True, True) _, msg = self.get_pwd_cookie(pwd) - html = self.j2s("msg", h1=msg, h2='ack', redir=dst) + h2 = 'continue' + html = self.j2s("msg", h1=msg, h2=h2, redir=dst) self.reply(html.encode("utf-8")) return True @@ -2976,7 +2985,7 @@ class HttpCli(object): self.get_pwd_cookie("x") dst = self.args.SRS + "?h" - h2 = 'ack' + h2 = 'continue' html = self.j2s("msg", h1="ok bye", h2=h2, redir=dst) self.reply(html.encode("utf-8")) return True @@ -3057,7 +3066,7 @@ class HttpCli(object): raise Pebkac(405, 'folder "/%s" already exists' % (vpath,)) try: - bos.makedirs(fn, vfs.flags["chmod_d"]) + bos.makedirs(fn, vf=vfs.flags) except OSError as ex: if ex.errno == errno.EACCES: raise Pebkac(500, "the server OS denied write-access") @@ -3099,8 +3108,22 @@ class HttpCli(object): with open(fsenc(fn), "wb") as f: f.write(b"`GRUNNUR`\n") - if "chmod_f" in vfs.flags: - os.fchmod(f.fileno(), vfs.flags["chmod_f"]) + if "fperms" in vfs.flags: + set_fperms(f, vfs.flags) + + dbv, vrem = vfs.get_dbv(rem) + self.conn.hsrv.broker.say( + "up2k.hash_file", + dbv.realpath, + dbv.vpath, + dbv.flags, + vrem, + sanitized, + self.ip, + bos.stat(fn).st_mtime, + self.uname, + True, + ) vpath = "{}/{}".format(self.vpath, sanitized).lstrip("/") self.redirect(vpath, "?edit") @@ -3174,7 +3197,7 @@ class HttpCli(object): ) upload_vpath = "{}/{}".format(vfs.vpath, rem).strip("/") if not nullwrite: - bos.makedirs(fdir_base, vfs.flags["chmod_d"]) + bos.makedirs(fdir_base, vf=vfs.flags) rnd, lifetime, xbu, xau = self.upload_flags(vfs) zs = self.uparam.get("want") or self.headers.get("accept") or "" @@ -3207,7 +3230,7 @@ class HttpCli(object): if rnd: fname = rand_name(fdir, fname, rnd) - open_args = {"fdir": fdir, "suffix": suffix} + open_args = {"fdir": fdir, "suffix": suffix, "vf": vfs.flags} if "replace" in self.uparam: if not self.can_delete: @@ -3269,11 +3292,8 @@ class HttpCli(object): else: open_args["fdir"] = fdir - if "chmod_f" in vfs.flags: - open_args["chmod"] = vfs.flags["chmod_f"] - if p_file and not nullwrite: - bos.makedirs(fdir, vfs.flags["chmod_d"]) + bos.makedirs(fdir, vf=vfs.flags) # reserve destination filename f, fname = ren_open(fname, "wb", fdir=fdir, suffix=suffix) @@ -3377,7 +3397,7 @@ class HttpCli(object): if nullwrite: fdir = ap2 = "" else: - bos.makedirs(fdir, vfs.flags["chmod_d"]) + bos.makedirs(fdir, vf=vfs.flags) atomic_move(self.log, abspath, ap2, vfs.flags) abspath = ap2 sz = bos.path.getsize(abspath) @@ -3498,8 +3518,8 @@ class HttpCli(object): ft = "{}:{}".format(self.ip, self.addr[1]) ft = "{}\n{}\n{}\n".format(ft, msg.rstrip(), errmsg) f.write(ft.encode("utf-8")) - if "chmod_f" in vfs.flags: - os.fchmod(f.fileno(), vfs.flags["chmod_f"]) + if "fperms" in vfs.flags: + set_fperms(f, vfs.flags) except Exception as ex: suf = "\nfailed to write the upload report: {}".format(ex) @@ -3550,7 +3570,7 @@ class HttpCli(object): lim = vfs.get_dbv(rem)[0].lim if lim: fp, rp = lim.all(self.ip, rp, clen, vfs.realpath, fp, self.conn.hsrv.broker) - bos.makedirs(fp, vfs.flags["chmod_d"]) + bos.makedirs(fp, vf=vfs.flags) fp = os.path.join(fp, fn) rem = "{}/{}".format(rp, fn).strip("/") @@ -3618,15 +3638,17 @@ class HttpCli(object): zs = ub64enc(zb).decode("ascii")[:24].lower() dp = "%s/md/%s/%s/%s" % (dbv.histpath, zs[:2], zs[2:4], zs) self.log("moving old version to %s/%s" % (dp, mfile2)) - if bos.makedirs(dp, vfs.flags["chmod_d"]): + if bos.makedirs(dp, vf=vfs.flags): with open(os.path.join(dp, "dir.txt"), "wb") as f: f.write(afsenc(vrd)) - if "chmod_f" in vfs.flags: - os.fchmod(f.fileno(), vfs.flags["chmod_f"]) + if "fperms" in vfs.flags: + set_fperms(f, vfs.flags) elif hist_cfg == "s": dp = os.path.join(mdir, ".hist") try: bos.mkdir(dp, vfs.flags["chmod_d"]) + if "chown" in vfs.flags: + bos.chown(dp, vfs.flags["uid"], vfs.flags["gid"]) hidedir(dp) except: pass @@ -3665,8 +3687,8 @@ class HttpCli(object): wunlink(self.log, fp, vfs.flags) with open(fsenc(fp), "wb", self.args.iobuf) as f: - if "chmod_f" in vfs.flags: - os.fchmod(f.fileno(), vfs.flags["chmod_f"]) + if "fperms" in vfs.flags: + set_fperms(f, vfs.flags) sz, sha512, _ = hashcopy(p_data, f, None, 0, self.args.s_wr_slp) if lim: @@ -4907,11 +4929,8 @@ class HttpCli(object): else: rip = host - # safer than html_escape/quotep since this avoids both XSS and shell-stuff - pw = re.sub(r"[<>&$?`\"']", "_", self.pw or "hunter2") - vp = re.sub(r"[<>&$?`\"']", "_", self.uparam["hc"] or "").lstrip("/") - pw = pw.replace(" ", "%20") - vp = vp.replace(" ", "%20") + vp = (self.uparam["hc"] or "").lstrip("/") + pw = self.pw or "hunter2" if pw in self.asrv.sesa: pw = "hunter2" @@ -4920,14 +4939,14 @@ class HttpCli(object): args=self.args, accs=bool(self.asrv.acct), s="s" if self.is_https else "", - rip=rip, - ep=ep, - vp=vp, - rvp=vjoin(self.args.R, vp), - host=host, - hport=hport, + rip=html_sh_esc(rip), + ep=html_sh_esc(ep), + vp=html_sh_esc(vp), + rvp=html_sh_esc(vjoin(self.args.R, vp)), + host=html_sh_esc(host), + hport=html_sh_esc(hport), aname=aname, - pw=pw, + pw=html_sh_esc(pw), ) self.reply(html.encode("utf-8")) return True @@ -5351,15 +5370,16 @@ class HttpCli(object): raise Pebkac(500, "sqlite3 not found on server; unpost is disabled") raise Pebkac(500, "server busy, cannot unpost; please retry in a bit") - zs = self.uparam.get("filter") or "" - filt = re.compile(zs, re.I) if zs else None - lm = "ups %r" % (zs,) + sfilt = self.uparam.get("filter") or "" + nfi, vfi = str_anchor(sfilt) + lm = "ups %d%r" % (nfi, sfilt) if self.args.shr and self.vpath.startswith(self.args.shr1): shr_dbv, shr_vrem = self.vn.get_dbv(self.rem) else: shr_dbv = None + wret: dict[str, Any] = {} ret: list[dict[str, Any]] = [] t0 = time.time() lim = time.time() - self.args.unpost @@ -5381,7 +5401,13 @@ class HttpCli(object): x = self.conn.hsrv.broker.ask( "up2k.get_unfinished_by_user", self.uname, "" if bad_xff else self.ip ) - uret = x.get() + zdsa: dict[str, Any] = x.get() + uret: list[dict[str, Any]] = [] + if "timeout" in zdsa: + wret["nou"] = 1 + else: + uret = zdsa["f"] + nu = len(uret) if not self.args.unpost: allvols = [] @@ -5406,8 +5432,14 @@ class HttpCli(object): q = "select sz, rd, fn, at from up where ip=? and at>? order by at desc" for sz, rd, fn, at in cur.execute(q, (self.ip, lim)): vp = "/" + "/".join(x for x in [vol.vpath, rd, fn] if x) - if filt and not filt.search(vp): - continue + if nfi == 0 or (nfi == 1 and vfi in vp): + pass + elif nfi == 2: + if not vp.startswith(vfi): + continue + elif nfi == 3: + if not vp.endswith(vfi): + continue n -= 1 if not n: @@ -5427,6 +5459,8 @@ class HttpCli(object): if len(ret) > 2000: ret = ret[:2000] + if len(ret) >= 2000: + wret["oc"] = 1 for rv in ret: rv["vp"] = quotep(rv["vp"]) @@ -5446,6 +5480,13 @@ class HttpCli(object): ) rv["vp"] += "?k=" + fk[:nfk] + if not allvols: + wret["noc"] = 1 + ret = [] + + nc = len(ret) + ret = uret + ret + if shr_dbv: # translate vpaths from share-target to share-url # to satisfy access checks @@ -5460,12 +5501,11 @@ class HttpCli(object): for v in ret: v["vp"] = self.args.SR + v["vp"] - if not allvols: - ret = [{"kinshi": 1}] - - jtxt = '{"u":%s,"c":%s}' % (uret, json.dumps(ret, separators=(",\n", ": "))) - zi = len(uret.split('\n"pd":')) - 1 - self.log("%s #%d+%d %.2fsec" % (lm, zi, len(ret), time.time() - t0)) + wret["f"] = ret + wret["nu"] = nu + wret["nc"] = nc + jtxt = json.dumps(wret, separators=(",\n", ": ")) + self.log("%s #%d+%d %.2fsec" % (lm, nu, nc, time.time() - t0)) self.reply(jtxt.encode("utf-8", "replace"), mime="application/json") return True @@ -5480,8 +5520,8 @@ class HttpCli(object): raise Pebkac(500, "server busy, cannot list recent uploads; please retry") sfilt = self.uparam.get("filter") or "" - filt = re.compile(sfilt, re.I) if sfilt else None - lm = "ru %r" % (sfilt,) + nfi, vfi = str_anchor(sfilt) + lm = "ru %d%r" % (nfi, sfilt) self.log(lm) ret: list[dict[str, Any]] = [] @@ -5516,8 +5556,14 @@ class HttpCli(object): q = "select sz, rd, fn, ip, at from up where at>0 order by at desc" for sz, rd, fn, ip, at in cur.execute(q): vp = "/" + "/".join(x for x in [vol.vpath, rd, fn] if x) - if filt and not filt.search(vp): - continue + if nfi == 0 or (nfi == 1 and vfi in vp): + pass + elif nfi == 2: + if not vp.startswith(vfi): + continue + elif nfi == 3: + if not vp.endswith(vfi): + continue if not dots and "/." in vp: continue @@ -5591,7 +5637,7 @@ class HttpCli(object): self.reply(jtxt.encode("utf-8", "replace"), mime="application/json") return True - html = self.j2s("rups", this=self, v=jtxt) + html = self.j2s("rups", this=self, v=json_hesc(jtxt)) self.reply(html.encode("utf-8"), status=200) return True @@ -5655,15 +5701,15 @@ class HttpCli(object): raise Pebkac(500, "sqlite3 not found on server; sharing is disabled") raise Pebkac(500, "server busy, cannot create share; please retry in a bit") + skey = self.uparam.get("skey") or self.vpath.split("/")[-1] + if self.args.shr_v: - self.log("handle_eshare: " + self.req) + self.log("handle_eshare: " + skey) cur = idx.get_shr() if not cur: raise Pebkac(400, "huh, sharing must be disabled in the server config...") - skey = self.vpath.split("/")[-1] - rows = cur.execute("select un, t1 from sh where k = ?", (skey,)).fetchall() un = rows[0][0] if rows and rows[0] else "" diff --git a/copyparty/smbd.py b/copyparty/smbd.py index d5098de5..2b9b3d77 100644 --- a/copyparty/smbd.py +++ b/copyparty/smbd.py @@ -320,7 +320,7 @@ class SMB(object): self.hub.up2k.handle_mv(uname, "1.7.6.2", vp1, vp2) try: - bos.makedirs(ap2, vfs2.flags["chmod_d"]) + bos.makedirs(ap2, vf=vfs2.flags) except: pass diff --git a/copyparty/svchub.py b/copyparty/svchub.py index 751fd566..bd7562e4 100644 --- a/copyparty/svchub.py +++ b/copyparty/svchub.py @@ -51,6 +51,7 @@ from .util import ( HAVE_PSUTIL, HAVE_SQLITE3, HAVE_ZMQ, + RE_ANSI, URL_BUG, UTC, VERSIONS, @@ -60,7 +61,6 @@ from .util import ( HMaccas, ODict, alltrace, - ansi_re, build_netmap, expat_ver, gzip, @@ -1026,6 +1026,8 @@ class SvcHub(object): except: raise Exception("invalid --mv-retry [%s]" % (self.args.mv_retry,)) + al.js_utc = "false" if al.localtime else "true" + al.tcolor = al.tcolor.lstrip("#") if len(al.tcolor) == 3: # fc5 => ffcc55 al.tcolor = "".join([x * 2 for x in al.tcolor]) @@ -1409,9 +1411,9 @@ class SvcHub(object): if self.no_ansi: fmt = "%s %-21s %s\n" if "\033" in msg: - msg = ansi_re.sub("", msg) + msg = RE_ANSI.sub("", msg) if "\033" in src: - src = ansi_re.sub("", src) + src = RE_ANSI.sub("", src) elif c: if isinstance(c, int): msg = "\033[3%sm%s\033[0m" % (c, msg) diff --git a/copyparty/tftpd.py b/copyparty/tftpd.py index 82ef3726..6f5726b3 100644 --- a/copyparty/tftpd.py +++ b/copyparty/tftpd.py @@ -45,6 +45,7 @@ from .util import ( exclude_dotfiles, min_ex, runhook, + set_fperms, undot, vjoin, vsplit, @@ -388,8 +389,8 @@ class Tftpd(object): a = (self.args.iobuf,) ret = open(ap, mode, *a, **ka) - if wr and "chmod_f" in vfs.flags: - os.fchmod(ret.fileno(), vfs.flags["chmod_f"]) + if wr and "fperms" in vfs.flags: + set_fperms(ret, vfs.flags) return ret @@ -398,7 +399,9 @@ class Tftpd(object): if "*" not in vfs.axs.uwrite: yeet("blocked mkdir; folder not world-writable: /%s" % (vpath,)) - return bos.mkdir(ap, vfs.flags["chmod_d"]) + bos.mkdir(ap, vfs.flags["chmod_d"]) + if "chown" in vfs.flags: + bos.chown(ap, vfs.flags["uid"], vfs.flags["gid"]) def _unlink(self, vpath: str) -> None: # return bos.unlink(self._v2a("stat", vpath, *a)[1]) diff --git a/copyparty/th_srv.py b/copyparty/th_srv.py index e00c04e9..67413c10 100644 --- a/copyparty/th_srv.py +++ b/copyparty/th_srv.py @@ -269,8 +269,8 @@ class ThumbSrv(object): self.log("joined waiting room for %r" % (tpath,)) except: thdir = os.path.dirname(tpath) - chmod = 0o700 if self.args.free_umask else 0o755 - bos.makedirs(os.path.join(thdir, "w"), chmod) + chmod = bos.MKD_700 if self.args.free_umask else bos.MKD_755 + bos.makedirs(os.path.join(thdir, "w"), vf=chmod) inf_path = os.path.join(thdir, "dir.txt") if not bos.path.exists(inf_path): diff --git a/copyparty/up2k.py b/copyparty/up2k.py index 907347f5..ae5ed07f 100644 --- a/copyparty/up2k.py +++ b/copyparty/up2k.py @@ -399,12 +399,14 @@ class Up2k(object): return "{}" - def get_unfinished_by_user(self, uname, ip) -> str: + def get_unfinished_by_user(self, uname, ip) -> dict[str, Any]: + # returns dict due to ExceptionalQueue if PY2 or not self.reg_mutex.acquire(timeout=2): - return '[{"timeout":1}]' + return {"timeout": 1} ret: list[tuple[int, str, int, int, int]] = [] userset = set([(uname or "\n"), "*"]) + n = 1000 try: for ptop, tab2 in self.registry.items(): cfg = self.flags.get(ptop, {}).get("u2abort", 1) @@ -419,7 +421,6 @@ class Up2k(object): or (addr and addr != job["addr"]) ): continue - zt5 = ( int(job["t0"]), djoin(job["vtop"], job["prel"], job["name"]), @@ -428,6 +429,9 @@ class Up2k(object): len(job["hash"]), ) ret.append(zt5) + n -= 1 + if not n: + break finally: self.reg_mutex.release() @@ -444,7 +448,7 @@ class Up2k(object): } for (at, vp, sz, nn, nh) in ret ] - return json.dumps(ret2, separators=(",\n", ": ")) + return {"f": ret2} def get_unfinished(self) -> str: if PY2 or not self.reg_mutex.acquire(timeout=0.5): @@ -916,7 +920,7 @@ class Up2k(object): for vol in vols: try: # mkdir gonna happen at snap anyways; - bos.makedirs(vol.realpath, vol.flags["chmod_d"]) + bos.makedirs(vol.realpath, vf=vol.flags) dir_is_empty(self.log_func, not self.args.no_scandir, vol.realpath) except Exception as ex: self.volstate[vol.vpath] = "OFFLINE (cannot access folder)" @@ -2827,7 +2831,7 @@ class Up2k(object): # v5a -> v5b # store rd+fn rather than warks to support nohash vols try: - cur.execute("select ws, rd, fn from iu limit 1").fetchone() + cur.execute("select c, w, rd, fn from iu limit 1").fetchone() return except: pass @@ -3309,7 +3313,7 @@ class Up2k(object): reg, "up2k._get_volsize", ) - bos.makedirs(ap2, vfs.flags["chmod_d"]) + bos.makedirs(ap2, vf=vfs.flags) vfs.lim.nup(cj["addr"]) vfs.lim.bup(cj["addr"], cj["size"]) @@ -3445,7 +3449,7 @@ class Up2k(object): "wb", fdir=fdir, suffix="-%.6f-%s" % (ts, dip), - chmod=vf.get("chmod_f", -1), + vf=vf, ) f.close() return ret @@ -4304,7 +4308,7 @@ class Up2k(object): self.log(t, 1) raise Pebkac(405, t) - bos.makedirs(os.path.dirname(dabs), dvn.flags["chmod_d"]) + bos.makedirs(os.path.dirname(dabs), vf=dvn.flags) c1, w, ftime_, fsize_, ip, at = self._find_from_vpath( svn_dbv.realpath, srem_dbv @@ -4480,7 +4484,10 @@ class Up2k(object): vp = vjoin(dvp, rem) try: dvn, drem = self.vfs.get(vp, uname, False, True) - bos.mkdir(dvn.canonical(drem), dvn.flags["chmod_d"]) + dap = dvn.canonical(drem) + bos.mkdir(dap, dvn.flags["chmod_d"]) + if "chown" in dvn.flags: + bos.chown(dap, dvn.flags["uid"], dvn.flags["gid"]) except: pass @@ -4550,7 +4557,7 @@ class Up2k(object): is_xvol = svn.realpath != dvn.realpath - bos.makedirs(os.path.dirname(dabs), dvn.flags["chmod_d"]) + bos.makedirs(os.path.dirname(dabs), vf=dvn.flags) if is_dirlink: dlabs = absreal(sabs) @@ -5062,7 +5069,7 @@ class Up2k(object): "wb", fdir=pdir, suffix="-%.6f-%s" % (job["t0"], dip), - chmod=vf.get("chmod_f", -1), + vf=vf, ) try: abspath = djoin(pdir, job["tnam"]) diff --git a/copyparty/util.py b/copyparty/util.py index 14768e6e..15b1924b 100644 --- a/copyparty/util.py +++ b/copyparty/util.py @@ -155,7 +155,9 @@ except: HAVE_PSUTIL = False try: - if os.environ.get("PRTY_NO_MAGIC"): + if os.environ.get("PRTY_NO_MAGIC") or ( + ANYWIN and not os.environ.get("PRTY_FORCE_MAGIC") + ): raise Exception() import magic @@ -241,7 +243,18 @@ except: BITNESS = struct.calcsize("P") * 8 -ansi_re = re.compile("\033\\[[^mK]*[mK]") +RE_ANSI = re.compile("\033\\[[^mK]*[mK]") +RE_HTML_SH = re.compile(r"[<>&$?`\"';]") +RE_CTYPE = re.compile(r"^content-type: *([^; ]+)", re.IGNORECASE) +RE_CDISP = re.compile(r"^content-disposition: *([^; ]+)", re.IGNORECASE) +RE_CDISP_FIELD = re.compile( + r'^content-disposition:(?: *|.*; *)name="([^"]+)"', re.IGNORECASE +) +RE_CDISP_FILE = re.compile( + r'^content-disposition:(?: *|.*; *)filename="(.*)"', re.IGNORECASE +) +RE_MEMTOTAL = re.compile("^MemTotal:.* kB") +RE_MEMAVAIL = re.compile("^MemAvailable:.* kB") BOS_SEP = ("%s" % (os.sep,)).encode("ascii") @@ -486,11 +499,11 @@ def read_ram() -> tuple[float, float]: with open("/proc/meminfo", "rb", 0x10000) as f: zsl = f.read(0x10000).decode("ascii", "replace").split("\n") - p = re.compile("^MemTotal:.* kB") + p = RE_MEMTOTAL zs = next((x for x in zsl if p.match(x))) a = int((int(zs.split()[1]) / 0x100000) * 100) / 100 - p = re.compile("^MemAvailable:.* kB") + p = RE_MEMAVAIL zs = next((x for x in zsl if p.match(x))) b = int((int(zs.split()[1]) / 0x100000) * 100) / 100 except: @@ -1585,7 +1598,8 @@ def ren_open(fname: str, *args: Any, **kwargs: Any) -> tuple[typing.IO[Any], str fun = kwargs.pop("fun", open) fdir = kwargs.pop("fdir", None) suffix = kwargs.pop("suffix", None) - chmod = kwargs.pop("chmod", -1) + vf = kwargs.pop("vf", None) + fperms = vf and "fperms" in vf if fname == os.devnull: return fun(fname, *args, **kwargs), fname @@ -1629,11 +1643,11 @@ def ren_open(fname: str, *args: Any, **kwargs: Any) -> tuple[typing.IO[Any], str fp2 = os.path.join(fdir, fp2) with open(fsenc(fp2), "wb") as f2: f2.write(orig_name.encode("utf-8")) - if chmod >= 0: - os.fchmod(f2.fileno(), chmod) + if fperms: + set_fperms(f2, vf) - if chmod >= 0: - os.fchmod(f.fileno(), chmod) + if fperms: + set_fperms(f, vf) return f, fname @@ -1695,14 +1709,10 @@ class MultipartParser(object): self.args = args self.headers = http_headers - self.re_ctype = re.compile(r"^content-type: *([^; ]+)", re.IGNORECASE) - self.re_cdisp = re.compile(r"^content-disposition: *([^; ]+)", re.IGNORECASE) - self.re_cdisp_field = re.compile( - r'^content-disposition:(?: *|.*; *)name="([^"]+)"', re.IGNORECASE - ) - self.re_cdisp_file = re.compile( - r'^content-disposition:(?: *|.*; *)filename="(.*)"', re.IGNORECASE - ) + self.re_ctype = RE_CTYPE + self.re_cdisp = RE_CDISP + self.re_cdisp_field = RE_CDISP_FIELD + self.re_cdisp_file = RE_CDISP_FILE self.boundary = b"" self.gen: Optional[ @@ -2244,6 +2254,16 @@ def find_prefix(ips: list[str], cidrs: list[str]) -> list[str]: return ret +def html_sh_esc(s: str) -> str: + s = re.sub(RE_HTML_SH, "_", s).replace(" ", "%20") + s = s.replace("\r", "_").replace("\n", "_") + return s + + +def json_hesc(s: str) -> str: + return s.replace("<", "\\u003c").replace(">", "\\u003e").replace("&", "\\u0026") + + def html_escape(s: str, quot: bool = False, crlf: bool = False) -> str: """html.escape but also newlines""" s = s.replace("&", "&").replace("<", "<").replace(">", ">") @@ -2376,6 +2396,21 @@ def ujoin(rd: str, fn: str) -> str: return rd or fn +def str_anchor(txt) -> tuple[int, str]: + if not txt: + return 0, "" + txt = txt.lower() + a = txt.startswith("^") + b = txt.endswith("$") + if not b: + if not a: + return 1, txt # ~ + return 2, txt[1:] # ^ + if not a: + return 3, txt[:-1] # $ + return 4, txt[1:-1] # ^$ + + def log_reloc( log: "NamedLogger", re: dict[str, str], @@ -2563,6 +2598,14 @@ def lsof(log: "NamedLogger", abspath: str) -> None: log("lsof failed; " + min_ex(), 3) +def set_fperms(f: Union[typing.BinaryIO, typing.IO[Any]], vf: dict[str, Any]) -> None: + fno = f.fileno() + if "chmod_f" in vf: + os.fchmod(fno, vf["chmod_f"]) + if "chown" in vf: + os.fchown(fno, vf["uid"], vf["gid"]) + + def _fs_mvrm( log: "NamedLogger", src: str, dst: str, atomic: bool, flags: dict[str, Any] ) -> bool: @@ -4169,7 +4212,12 @@ def load_resource(E: EnvParams, name: str, mode="rb") -> IO[bytes]: stream = codecs.getreader(enc)(stream) return stream - return open(os.path.join(E.mod, name), mode, encoding=enc) + ap = os.path.join(E.mod, name) + + if PY2: + return codecs.open(ap, "r", encoding=enc) # type: ignore + + return open(ap, mode, encoding=enc) class Pebkac(Exception): diff --git a/copyparty/web/browser.html b/copyparty/web/browser.html index a642e9a9..ebf41f8e 100644 --- a/copyparty/web/browser.html +++ b/copyparty/web/browser.html @@ -109,7 +109,7 @@ {%- for f in files %} {{ f.lead }}{{ f.name|e }}{{ f.sz }} {%- if f.tags is defined %} - {%- for k in taglist %}{{ f.tags[k] }}{%- endfor %} + {%- for k in taglist %}{{ f.tags[k]|e }}{%- endfor %} {%- endif %}{{ f.ext }}{{ f.dt }} {%- endfor %} diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index f1368912..02549c9f 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -3,6 +3,7 @@ var XHR = XMLHttpRequest, img_re = /\.(a?png|avif|bmp|gif|heif|jpe?g|jfif|svg|webp|webm|mkv|mp4|m4v|mov)(\?|$)/i; +// please add translations in alphabetic order, but keep "eng" and "nor" first var Ls = { "eng": { "tt": "English", @@ -229,6 +230,7 @@ var Ls = { "ct_qdel": 'when deleting files, only ask for confirmation once">qdel', "ct_dir1st": 'sort folders before files">📁 first', "ct_nsort": 'natural sort (for filenames with leading digits)">nsort', + "ct_utc": 'show all datetimes in UTC">UTC', "ct_readme": 'show README.md in folder listings">📜 readme', "ct_idxh": 'show index.html instead of folder listing">htm', "ct_sbars": 'show scrollbars">⟊', @@ -856,6 +858,7 @@ var Ls = { "ct_qdel": 'sletteknappen spør bare én gang om bekreftelse">hurtig🗑️', "ct_dir1st": 'sorter slik at mapper kommer foran filer">📁 først', "ct_nsort": 'naturlig sortering (forstår tall i filnavn)">nsort', + "ct_utc": 'bruk UTC for alle klokkeslett">UTC', "ct_readme": 'vis README.md nedenfor filene">📜 readme', "ct_idxh": 'vis index.html istedenfor fil-liste">htm', "ct_sbars": 'vis rullgardiner / skrollefelt">⟊', @@ -1257,7 +1260,6 @@ var Ls = { "lang_set": "passer det å laste siden på nytt?", }, - "chi": { // 以 //m 结尾的行是未经验证的机器翻译 "tt": "中文", @@ -1483,6 +1485,7 @@ var Ls = { "ct_qdel": '删除文件时,只需确认一次">快删', //m "ct_dir1st": '在文件之前排序文件夹">📁 排序', "ct_nsort": '正确排序以数字开头的文件名">数字排序', //m + "ct_utc": '所有时间请使用UTC">UTC', //m "ct_readme": '在文件夹列表中显示 README.md">📜 readme', "ct_idxh": '显示 index.html 代替文件夹列表">htm', "ct_sbars": '显示滚动条">⟊', @@ -1884,9 +1887,3143 @@ var Ls = { "lang_set": "刷新以使更改生效?", }, + "deu": { + "tt": "Deutsch", + + "cols": { + "c": "Aktionen", + "dur": "Dauer", + "q": "Qualität / Bitrate", + "Ac": "Audiocodec", + "Vc": "Videocodec", + "Fmt": "Format / Container", + "Ahash": "Audio Checksumme", + "Vhash": "Video Checksumme", + "Res": "Auflösung", + "T": "Dateityp", + "aq": "Audioqualität / Bitrate", + "vq": "Videoqualität / Bitrate", + "pixfmt": "Subsampling / Pixelstruktur", + "resw": "horizontale Auflösung", + "resh": "vertikale Auflösung", + "chs": "Audiokanäle", + "hz": "Abtastrate" + }, + + "hks": [ + [ + "misc", + ["ESC", "Dinge schliessen"], + + "file-manager", + ["G", "zwischen Liste und Gitter wechseln"], + ["T", "zwischen Vorschaubildern und Symbolen wechseln"], + ["⇧ A/D", "Vorschaubildergrösse ändern"], + ["STRG-K", "Auswahl löschen"], + ["STRG-X", "Auswahl ausschneiden"], + ["STRG-C", "Auswahl in Zwischenablage kopieren"], + ["STRG-V", "Zwischenablage hier einfügen"], + ["Y", "Auswahl herunterladen"], + ["F2", "Auswahl umbenennen"], + + "file-list-sel", + ["LEER", "Dateiauswahl aktivieren"], + ["↑/↓", "Cursor verschieben"], + ["STRG ↑/↓", "Cursor und Bildschirm verschieben"], + ["⇧ ↑/↓", "Vorherige / nächste Datei auswählen"], + ["STRG-A", "Alle Dateien / Ordner auswählen"], + ], [ + "navigation", + ["B", "Zwischen Brotkrumen und Navpane wechseln"], + ["I/K", "vorheriger / nächster Ordner"], + ["M", "übergeordneter Ordner (oder Vorherigen einklappen)"], + ["V", "Zwischen Textdateien und Navpane wechseln"], + ["A/D", "Grösse der Navpane ändern"], + ], [ + "audio-player", + ["J/L", "Vorheriger / nächster Song"], + ["U/O", "10 Sek. vor- / zurückspringen"], + ["0..9", "zu 0%..90% springen"], + ["P", "Wiedergabe / Pause"], + ["S", "aktuell abgespielten Song auswählen"], + ["Y", "Sing herunterladen"], + ], [ + "image-viewer", + ["J/L, ←/→", "vorheriges / nächstes Bild"], + ["Pos1/Ende", "erstes / letztes Bild"], + ["F", "Vollbild"], + ["R", "im Uhrzeigersinn drehen"], + ["⇧ R", "gegen den Uhrzeigensinn drehen"], + ["S", "Bild auswählen"], + ["Y", "Bild herunterladen"], + ], [ + "video-player", + ["U/O", "10 Sek. vor- / zurückspringen"], + ["P/K/LEER", "Wiedergabe / Pause"], + ["C", "continue playing next"], + ["V", "Wiederholungs-Wiedergabe (Loop)"], + ["M", "Stummschalten"], + ["[ und ]", "Loop-Interval einstellen"], + ], [ + "textfile-viewer", + ["I/K", "vorherige / nächste Datei"], + ["M", "Textdatei schliessen"], + ["E", "Textdatei bearbeiten"], + ["S", "Textdatei auswählen (für Ausschneiden / Kopieren / Umbenennen)"], + ] + ], + + "m_ok": "OK", + "m_ng": "Abbrechen", + + "enable": "Aktivieren", + "danger": "ACHTUNG", + "clipped": "in Zwischenablage kopiert", + + "ht_s1": "Sekunde", + "ht_s2": "Sekunden", + "ht_m1": "Minute", + "ht_m2": "Minuten", + "ht_h1": "Stunde", + "ht_h2": "Stunden", + "ht_d1": "Tag", + "ht_d2": "Tage", + "ht_and": " und ", + + "goh": "Einstellungen", + "gop": 'zum vorherigen Ordner springen">vorh.', + "gou": 'zum übergeordneter Ordner springen">hoch', + "gon": 'zum nächsten Ordner springen">nächst.', + "logout": "Abmelden ", + "access": " Zugriff", + "ot_close": "Submenu schliessen", + "ot_search": "Dateien nach Attributen, Pfad/Name, Musiktags oder beliebiger Kombination suchen$N$N<code>foo bar</code> = muss «foo» und «bar» enthalten,$N<code>foo -bar</code> = muss «foo» aber nicht «bar» enthalten,$N<code>^yana .opus$</code> = beginnt mit «yana» und ist «opus»-Datei$N<code>"try unite"</code> = genau «try unite» enthalten$N$NDatumsformat ist iso-8601, z.B.$N<code>2009-12-31</code> oder <code>2020-09-12 23:30:00</code>", + "ot_unpost": "unpost: lösche deine letzten Uploads oder breche unvollständige ab", + "ot_bup": "bup: Basic Uploader, unterstützt sogar Neuheiten wie Netscape 4.0", + "ot_mkdir": "mkdir: Neuen Ordner erstellen", + "ot_md": "new-md: Neues Markdown-Dokument erstellen", + "ot_msg": "msg: Eine Nachricht an das Server-Log schicken", + "ot_mp": "Media Player-Optionen", + "ot_cfg": "Konfigurationsoptionen", + "ot_u2i": 'up2k: Dateien hochladen (wenn du Schreibrechte hast) oder in den Suchmodus wechseln, um zu prüfen, ob sie bereits auf dem Server existieren$N$NUploads sind fortsetzbar, multithreaded und behalten Dateizeitstempel, verbrauchen aber mehr CPU als [🎈]  (der einfache Uploader)

während Uploads wird dieses Symbol zu einem Fortschrittsanzeiger!', + "ot_u2w": 'up2k: Dateien mit Wiederaufnahme-Unterstützung hochladen (Browser schließen und später dieselben Dateien erneut hochladen)$N$Nmultithreaded, behält Dateizeitstempel, verbraucht aber mehr CPU als [🎈]  (der einfache Uploader)

während Uploads wird dieses Symbol zu einem Fortschrittsanzeiger!', + "ot_noie": 'Bitte benutze Chrome / Firefox / Edge', + + "ab_mkdir": "Ordner erstellen", + "ab_mkdoc": "Markdown Doc erstellen", + "ab_msg": "Nachricht an Server Log senden", + + "ay_path": "zu Ordnern springen", + "ay_files": "zu Dateien springen", + + "wt_ren": "ausgewählte Elemente umbenennen$NHotkey: F2", + "wt_del": "ausgewählte Elemente löschen$NHotkey: STRG-K", + "wt_cut": "ausgewählte Elemente ausschneiden <small>(um sie dann irgendwo anders einzufügen)</small>$NHotkey: STRG-X", + "wt_cpy": "ausgewählte Elemente in Zwischenablage kopieren$N(um sie dann irgendwo anders einzufügen)$NHotkey: ctrl-C", + "wt_pst": "zuvor ausgeschnittenen / kopierte Elemente einfügen$NHotkey: STRG-V", + "wt_selall": "alle Dateien auswählen$NHotkey: STRG-A (wenn Datei fokusiert)", + "wt_selinv": "Auswahl invertieren", + "wt_zip1": "Diesen Ordner als Archiv herunterladen", + "wt_selzip": "Auswahl als Archiv herunterladen", + "wt_seldl": "Auswahl als separate Dateien herunterladen$NHotkey: Y", + "wt_npirc": "kopiere Titelinfo als IRC-formattierten Text", + "wt_nptxt": "kopiere Titelinfo als Text", + "wt_m3ua": "Zu M3U-Wiedergabeliste hinzufügen (wähle später 📻copy)", + "wt_m3uc": "M3U-Wiedergabeliste in Zwischenablage kopieren", + "wt_grid": "Zwischen Gitter und Liste wechseln$NHotkey: G", + "wt_prev": "Vorheriger Titel$NHotkey: J", + "wt_play": "Wiedergabe / Pause$NHotkey: P", + "wt_next": "Nächster Titel$NHotkey: L", + + "ul_par": "Parallele Uploads:", + "ut_rand": "Zufällige Dateinamen", + "ut_u2ts": "Zuletzt geändert-Zeitstempel von$Ndeinem Dateisystem auf den Server übertragen\">📅", + "ut_ow": "Existierende Dateien auf dem Server überschreiben?$N🛡️: Nie (generiert einen neuen Dateinamen)$N🕒: Überschreiben, wenn Server-Datei älter ist als meine$N♻️: Überschreiben, wenn der Dateiinhalt anders ist", + "ut_mt": "Andere Dateien während des Uploads hashen$N$Nsolltest du deaktivieren, falls deine CPU oder Festplatte zum Flaschenhals werden könnte", + "ut_ask": 'Vor dem Upload nach Bestätigung fragen">💭', + "ut_pot": "Verbessert Upload-Geschwindigkeit$Nindem das UI weniger komplex gemacht wird", + "ut_srch": "nicht wirklich hochladen, stattdessen prüfen ob Datei bereits auf dem Server existiert (scannt alle Ordner, die du lesen kannst)", + "ut_par": "setze auf 0 zum Pausieren$N$Nerhöhe, wenn deine Verbindung langsam / instabil ist$N$lass auf 1 im LAN oder wenn die Festplatte auf dem Server ein Flaschenhals ist", + "ul_btn": "Dateien / Ordner hier
ablegen (oder klick mich)", + "ul_btnu": "U P L O A D", + "ul_btns": "S U C H E N", + + "ul_hash": "hash", + "ul_send": "senden", + "ul_done": "fertig", + "ul_idle1": "keine Uploads in der Warteschlange", + "ut_etah": "durchschnittl. <em>hashing</em> Geschw. & gesch. Restzeit", + "ut_etau": "durchschnittl. <em>upload</em> Geschw. & gesch. Restzeit", + "ut_etat": "durchschnittl. <em>total</em> Geschw. & gesch. Restzeit", + + "uct_ok": "Erfolgreich abgeschlossen", + "uct_ng": "no-good: fehlgeschlagen / abgelehnt / nicht gefunden", + "uct_done": "ok and ng zusammen", + "uct_bz": "wird gehasht oder hochgeladen", + "uct_q": "ausstehend", + + "utl_name": "Dateiname", + "utl_ulist": "Liste", + "utl_ucopy": "kopieren", + "utl_links": "Links", + "utl_stat": "Status", + "utl_prog": "Fortschritt", + + // keep short: + "utl_404": "404", + "utl_err": "Fehler", + "utl_oserr": "OS-Fehler", + "utl_found": "gefunden", + "utl_defer": "zurückstellen", + "utl_yolo": "YOLO", + "utl_done": "fertig", + + "ul_flagblk": "Die Dateien wurden zur Warteschlange hinzugefügt
jedoch ist up2k gerade in einem anderen Browsertab aktiv.
Ich warte, bis der Upload abgeschlossen ist.", + "ul_btnlk": "Die Serverkonfiguration hat diese Einstellung gesperrt", + + "udt_up": "Upload", + "udt_srch": "Suchen", + "udt_drop": "hier ablegen", + + "u_nav_m": '
okay, was gibts??
Eingabe = Dateien (1 oder mehr)\nESC = 1 Ordner (inkl. Unterordner)', + "u_nav_b": 'Dateien1 Ordner', + + "cl_opts": "Schalter", + "cl_themes": "Themes", + "cl_langs": "Sprache", + "cl_ziptype": "Ordner Download", + "cl_uopts": "up2k Schalter", + "cl_favico": "Favicon", + "cl_bigdir": "grosse Ordner", + "cl_hsort": "#sort", + "cl_keytype": "Schlüsselnotation", + "cl_hiddenc": "Spalten verstecken", + "cl_hidec": "verstecken", + "cl_reset": "zurücksetzen", + "cl_hpick": "zum Verstecken, tippe auf Spaltenüberschriften in der Tabelle unten", + "cl_hcancel": "Spaltenbearbeitung abgebrochen", + + "ct_grid": '田 Das Raster™', + "ct_ttips": '◔ ◡ ◔">ℹ️ Tooltips', + "ct_thumb": 'In Raster-Ansicht, zwischen Icons und Vorschau wechseln$NHotkey: T">🖼️ Vorschaubilder', + "ct_csel": 'Benutze STRG und UMSCHALT für Dateiauswahl in Raster-Ansicht">sel', + "ct_ihop": 'Wenn die Bildanzeige geschlossen ist, scrolle runter zu den zuletzt angesehenen Dateien">g⮯', + "ct_dots": 'Verstecke Dateien anzeigen (wenn erlaubt durch Server)">dotfiles', + "ct_qdel": 'Nur einmal fragen, wenn mehrere Dateien gelöscht werden">qdel', + "ct_dir1st": 'Ordner vor Dateien sortieren">📁 zuerst', + "ct_nsort": 'Natürliche Sortierung (für Dateinamen mit führenden Ziffern)">nsort', + "ct_utc": 'Verwenden Sie UTC für alle Zeitangaben">UTC', //m + "ct_readme": 'README.md in Dateiliste anzeigen">📜 readme', + "ct_idxh": 'index.html anstelle von Dateiliste anzeigen">htm', + "ct_sbars": 'Scrollbars zeigen">⟊', + + "cut_umod": "Sollte die Datei bereits auf dem Server existieren, den 'Zuletzt geändert'-Zeitstempel an deine lokale Datei anpassen (benötigt Lese- und Löschrechte)\">re📅", + + "cut_turbo": "der YOLO-Knopf, den du wahrscheinlich NICHT aktivieren willst:$N$NBenutze ihn, falls du ne Menge Zeug hochladen wolltest und aus irgendeinem Grund neustarten musstest und du so schnell wie möglich weitermachen willst.$N$Ndies ersetzt den Hash-Check mit einem einfachen "Ist die Datei auf dem Server gleich gross?", wenn die Datei also anderen Inhalt hat, wird sie NICHT nochmal hochgeladen!$N$NDu solltest dieses Feature ausschalten, sobald der Upload fertig ist und dann die gleichen Dateien nochmal "hochladen", damit der Client sie verifizieren kann.\">turbo", + + "cut_datechk": "Funktioniert nur in kombination mit dem Turbo-Knopf$N$NReduziert den YOLO-Faktor ein bisschen; prüft, ob der Zeitstempel deiner Datei mit dem auf dem Server übereinstimmt$N$Nsollte theoretisch die meisten unfertigen / korrupten Uploads erwischen, ist aber nicht zu gebrauchen, um einen Prüfdurchgang nach einem Turbo-Upload zu machen\">date-chk", + + "cut_u2sz": "Grösse (in MiB) für jeden Upload-Chunk; mit grossen Werten fliegen die Bits besser über den Atlantik. Versuche kleine Werte, wenn du eine schlechte Verbindung hast (z.B. du benutzt mobile Daten in Deutschland)", + + "cut_flag": "Stelle sicher, dass nur ein Tab auf einmal Dateien hochlädt$N -- andere Tabs müssen diese Funktion auch aktiviert haben $N -- funktioniert nur bei Tabs mit der gleichen Domäne", + + "cut_az": "Lädt Dateien in alphabetischer Reihenfolge hoch, anstatt nach Dateigrösse$N$NAlphabethische Reihenfolge kann es einfacher machen, Server-Fehler mit naktem Auge zu erkennen, macht aber Uploads über Glassfaser / LAN etwas langsamer", + + "cut_nag": "Benachrichtigung über das Betriebssystem abgeben, wenn Upload fertig ist$N(nur wenn Browser oder Tab nicht im Vordergrund ist)", + "cut_sfx": "Spielt ein Ton ab, wenn Upload fertig ist$N(nur wenn Browser oder Tab nicht im Vordergrund ist)", + + "cut_mt": "Multithreading benutzen um Datei-Hashing zu beschleunigen$N$NDies nutzt Web-Workers und benötigt$Nmehr RAM (bis zu 512 MiB extra)$N$Nbeschleunigt HTTPS 30% schneller, HTTP um 4.5x\">mt", + + "cut_wasm": "benutzt WASM anstelle des Browser-eigenen Hashers; verbessert Geschwindigkeit auf Chromium-basierten Browsern, erhöht aber die CPU-Auslastung. Viele ältere Versionen von Chrome haben Memory-Leaks, die den gesamten RAM verbrauchen und dann crashen, wenn diese Funktion aktiviert ist.\">wasm", + + "cft_text": "Favicon Text (leer lassen und neuladen zum Deaktivieren)", + "cft_fg": "Vordergrundfarbe", + "cft_bg": "Hintergrundfarbe", + + "cdt_lim": "max. Anz. Dateien, die in einem Ordner gezeigt werden sollen", + "cdt_ask": "beim Runterscrollen nach $NAktion fragen statt mehr,$NDateien zu laden", + "cdt_hsort": "Menge an Sortierregeln (<code>,sorthref</code>) in Media-URLs enthalten sein sollen. Ein Wert von 0 sorgt dafür, dass Sortierregeln in Media-URLs ignoriert werden", + + "tt_entree": "Navpane anzeigen (Ordnerbaum Sidebar)$NHotkey: B", + "tt_detree": "Breadcrumbs anzeigen$NHotkey: B", + "tt_visdir": "zu ausgewähltem Ordner scrollen", + "tt_ftree": "zw. Ordnerbaum / Textdateien wechseln$NHotkey: V", + "tt_pdock": "übergeordnete Ordner in einem angedockten Fenster oben anzeigen", + "tt_dynt": "autom. wachsen wenn Baum wächst", + "tt_wrap": "Zeilenumbruch", + "tt_hover": "Beim Hovern überlange Zeilen anzeigen$N(Scrollen funktioniert nicht ausser $N  Cursor ist im linken Gutter)", + + "ml_pmode": "am Ende des Ordners...", + "ml_btns": "cmds", + "ml_tcode": "transcodieren", + "ml_tcode2": "transcodieren zu", + "ml_tint": "färben", + "ml_eq": "Audio Equalizer", + "ml_drc": "Dynamic Range Compressor", + + "mt_loop": "Song wiederholen\">🔁", + "mt_one": "Wiedergabe nach diesem Song beenden\">1️⃣", + "mt_shuf": "Zufällige Wiedergabe im Ordner\">🔀", + "mt_aplay": "automatisch abspielen, wenn der Link, mit dem du auf den Server zugreifst, eine Titel-ID enthält$N$NDeaktivieren verhindert auch, dass die Seiten-URL bei Musikwiedergabe mit Titel-IDs aktualisiert wird, um Autoplay zu verhindern, falls diese Einstellungen verloren gehen, die URL aber bestehen bleibt\">a▶", + "mt_preload": "nächsten Titel gegen Ende vorladen für nahtlose Wiedergabe\">Vorladen", + "mt_prescan": "vor Ende des letzten Titels zum nächsten Ordner wechseln,$Ndamit der Browser die$NWiedergabe nicht stoppt\">Navigation", + "mt_fullpre": "versuchen, den gesamten Titel vorzuladen;$N✅ bei unzuverlässiger Verbindung aktivieren,$N❌ bei langsamer Verbindung deaktivieren\">vollständig", + "mt_fau": "auf Handys verhindern, dass Musik stoppt, wenn der nächste Titel nicht schnell genug vorlädt (kann zu fehlerhafter Tag-Anzeige führen)\">☕️", + "mt_waves": "Wellenform-Suchleiste:$NAudio-Amplitude in der Leiste anzeigen\">~s", + "mt_npclip": "Buttons zum Kopieren des aktuellen Titels anzeigen\">/np", + "mt_m3u_c": "Buttons zum Kopieren der$Nausgewählten Titel als m3u8-Wiedergabeliste anzeigen\">📻", + "mt_octl": "OS-Integration (Media-Hotkeys/OSD)\">os-ctl", + "mt_oseek": "Suchen via OS-Integration erlauben$N$NHinweis: auf einigen Geräten (iPhones)$Nersetzt dies den nächsten-Titel-Button\">Suchen", + "mt_oscv": "Albumcover in OSD anzeigen\">Cover", + "mt_follow": "den spielenden Titel im Blick behalten\">🎯", + "mt_compact": "kompakte Steuerelemente\">⟎", + "mt_uncache": "Cache leeren  (probier das, wenn dein Browser$Neine defekte Kopie eines Titels zwischenspeichert und sich weigert, ihn abzuspielen)\">Cache leeren", + "mt_mloop": "offenen Ordner wiederholen\">🔁 Schleife", + "mt_mnext": "nächsten Ordner laden und fortfahren\">📂 nächster", + "mt_mstop": "Wiedergabe beenden\">⏸ Stop", + "mt_cflac": "FLAC / WAV zu OPUS konvertierebn\">flac", + "mt_caac": "AAC / M4A zu OPUS konvertieren\">aac", + "mt_coth": "Convertiere alle Dateien (die nicht MP3 sind) zu OPUS\">oth", + "mt_c2opus": "Beste Wahl für Desktops, Laptops, Android\">opus", + "mt_c2owa": "opus-weba, für iOS 17.5 und neuer\">owa", + "mt_c2caf": "opus-caf, für iOS 11 bis 17\">caf", + "mt_c2mp3": "benutze dieses Format für ältere Geräte\">mp3", + "mt_c2ok": "Gute Wahl, Chef!", + "mt_c2nd": "Das ist nicht das empfohlene Ausgabeformat für dein Gerät, aber passt schon", + "mt_c2ng": "Dein Gerät scheint dieses Ausgabeformat nicht zu unterstützen, aber lass trotzdem mal probieren", + "mt_xowa": "Es gibt Bugs in iOS, die die Hintergrund-Wiedergabe mit diesem Format verhindern; bitte nutze caf oder mp3 stattdessen", + "mt_tint": "Hintergrundlevel (0-100) auf der Seekbar$Num Buffern weniger ablenkend zu machen", + "mt_eq": "Aktiviert Equalizer und Lautstärkeregelung;$N$Nboost <code>0</code> = Standard 100% Lautstärke (unverändert)$N$Nwidth <code>1  </code> = Standard Stereo (unverändert)$Nwidth <code>0.5</code> = 50% Links-Rechts-Crossfeed$Nwidth <code>0  </code> = Mono$N$Nboost <code>-0.8</code> & width <code>10</code> = Gesangsentfernung :^)$N$NDer Equalizer macht nahtlose Alben vollständig nahtlos, also lass' ihn mit allen Werten auf Null (außer width = 1) aktiviert, wenn dir das wichtig ist", + "mt_drc": "Aktiviert den Dynamic Range Compressor (Lautstärkeglättung/-begrenzung); aktiviert auch den Equalizer zum Ausgleich, setze alle EQ-Felder außer 'width' auf 0, wenn du das nicht willst$N$Nsenkt die Lautstärke von Audio über SCHWELLENWERT dB; für jedes VERHÄLTNIS dB über SCHWELLENWERT gibt es 1 dB Ausgabe, also bedeuten Standardwerte von tresh -24 und ratio 12, dass es nie lauter als -22 dB werden sollte und der Equalizer-Boost sicher auf 0.8 oder sogar 1.8 mit ATK 0 und einem großen RLS wie 90 erhöht werden kann (funktioniert nur in Firefox; in anderen Browsern ist RLS max. 1)$N$N(siehe Wikipedia, dort wird es viel besser erklärt)", + + "mb_play": "Abspielen", + "mm_hashplay": "Diese Audiodatei abspielen?", + "mm_m3u": "Drücke Eingabe/OK zum Abspielen\nDrücke ESC/Abbrechen zum Bearbeiten", + "mp_breq": "Benötigt Firefox 82+ oder Chrome 73+ oder iOS 15+", + "mm_bload": "Lädt...", + "mm_bconv": "Konvertiere zu {0}, bitte warte...", + "mm_opusen": "Dein Browser kann AAC- / M4A-Dateien nicht abspielen;\nUmwandlung zu Opus ist jetzt aktiv", + "mm_playerr": "Wiedergabefehler: ", + "mm_eabrt": "Der Wiedergabeversuch wurde abgebrochen", + "mm_enet": "Dein Internet läuft auf Edge, wa?", + "mm_edec": "Die Datei scheint beschädigt zu sein??", + "mm_esupp": "Dein Browser versteht dieses Audioformat nicht", + "mm_eunk": "Unbekannter Fehler", + "mm_e404": "Konnte Datei nicht abspielen; Fehler 404: Datei nicht gefunden.", + "mm_e403": "Konnte Datei nicht abspielen; Fehler 403: Zugriff verweigert.\n\nDrücke F5 zum Neuladen, vielleicht wurdest du abgemeldet", + "mm_e500": "Konnte Datei nicht abspielen; Fehler 500: Prüfe die Serverlogs.", + "mm_e5xx": "Konnte Datei nicht abspielen; Server Fehler ", + "mm_nof": "finde keine weiteren Audiodateien in der Nähe", + "mm_prescan": "Suche nach Musik zum Abspielen...", + "mm_scank": "Nächster Song gefunden:", + "mm_uncache": "Cache geleert; Alle Songs werden beim nächsten Abspielversuch neu heruntergeladen", + "mm_hnf": "dieser Song existiert nicht mehr", + + "im_hnf": "dieses Bild existiert nicht mehr", + + "f_empty": 'Dieser Ordner ist leer', + "f_chide": 'Dies blendet die Spalte «{0}» aus\n\nDu kannst Spalten in den Einstellungen wieder einblenden.', + "f_bigtxt": "Diese Datei ist {0} MiB gross -- Sicher, dass du sie als Text anzeigen willst?", + "f_bigtxt2": "Möchtest du stattdessen nur das Ende der Datei anzeigen? Das aktiviert ausserdem die Folgen- und Verfolgen-Funktion, welche neu hinzugefügte Textzeilen in Echtzeit anzeigt", + "fbd_more": '
zeige {0} von {1} Dateien; {2} anzeigen oder alle anzeigen
', + "fbd_all": '
zeige {0} von {1} Dateien; alle anzeigen
', + "f_anota": "nur {0} der {1} Elemente wurden ausgewählt;\num den gesamten Ordner auszuwählen, zuerst nach unten scrollen", + + "f_dls": 'die Dateilinks im aktuellen Ordner wurden\nin Downloadlinks geändert', + + "f_partial": "Um eine Datei sicher herunterzuladen, die gerade hochgeladen wird, klicke bitte die Datei mit dem gleichen Namen, aber ohne die .PARTIAL-Endung. Bitte drücke Abbrechen oder Escape, um dies zu tun.\n\nWenn du auf OK / Eingabe drückst, ignorierst du diese Warnung und lädst die .PARTIAL-Datei herunter, die ziemlich sicher beschädigte Daten enthält.", + + "ft_paste": "{0} Elemente einfügen$NHotkey: STRG-V", + "fr_eperm": 'Umbenennen fehlgeschlagen:\nDir fehlt die "Verschieben"-Berechtigung in diesem Ordner', + "fd_eperm": 'Löschen fehlgeschlagen:\nDir fehlt die "Löschen"-Berechtigung in diesem Ordner', + "fc_eperm": 'Ausschneiden fehlgeschlagen:\nDir fehlt die "Verschieben"-Berechtigung in diesem Ordner', + "fp_eperm": 'Einfügen fehlgeschlagen:\nDir fehlt die "Schreiben"-Berechtigung in diesem Ordner', + "fr_emore": "Wähle mindestens ein Element zum Umbenennen aus", + "fd_emore": "Wähle mindestens ein Element zum Löschen aus", + "fc_emore": "Wähle mindestens ein Element zum Ausschneiden aus", + "fcp_emore": "Wähle mindestens ein Element aus, um es in die Zwischenablage zu kopieren", + + "fs_sc": "Teile diesen Ordner", + "fs_ss": "Teile die ausgewählten Dateien", + "fs_just1d": "Du kannst nicht mehrere Ordner auswählen \noder Dateien und Ordner in der Auswahl mischen.", + "fs_abrt": "❌ Abbrechen", + "fs_rand": "🎲 Zufallsname", + "fs_go": "✅ Share erstellen", + "fs_name": "Name", + "fs_src": "Quelle", + "fs_pwd": "Passwort", + "fs_exp": "Ablauf", + "fs_tmin": "Minuten", + "fs_thrs": "Stunden", + "fs_tdays": "Tage", + "fs_never": "nie", + "fs_pname": "optionaler Linkname; zufällig wenn leer", + "fs_tsrc": "zu teilende Datei oder Ordner", + "fs_ppwd": "optionales Passwort", + "fs_w8": "erstelle Share...", + "fs_ok": "drücke Eingabe/OK für Zwischenablage\ndrücke ESC/Abbrechen zum Schliessen", + + "frt_dec": "Kann Fälle von beschädigten Dateien beheben\">url-decode", + "frt_rst": "Geänderte Dateinamen auf Orginale zurücksetzen\">↺ zurücksetzen", + "frt_abrt": "Abbrechen und dieses Fenster schliessen\">❌ abbrechen", + "frb_apply": "ÜBERNEHMEN", + "fr_adv": "Stapel-/Metadaten-/Musterumbenennung\">erweitert", + "fr_case": "Groß-/Kleinschreibung beachten (Regex)\">Großschreibung", + "fr_win": "Windows-kompatible Namen; ersetzt <>:"\\|?* durch japanische Fullwidth-Zeichen\">win", + "fr_slash": "Ersetzt / durch ein Zeichen, das keine neuen Ordner erstellt\">no /", + "fr_re": "Regex-Suchmuster für Originaldateinamen; Erfassungsgruppen können im Formatfeld unten als <code>(1)</code> und <code>(2)</code> usw. referenziert werden", + "fr_fmt": "inspiriert von foobar2000:$N<code>(title)</code> wird durch Songtitel ersetzt,$N<code>[(artist) - ](title)</code> überspringt [diesen] Teil falls Interpret leer$N<code>$lpad((tn),2,0)</code> füllt die Titelnummer auf 2 Ziffern auf", + "fr_pdel": "Löschen", + "fr_pnew": "Speichern als", + "fr_pname": "Gib der Vorlage einen Namen", + "fr_aborted": "Abgebrochen", + "fr_lold": "Alter Name", + "fr_lnew": "Neuer Name", + "fr_tags": "Tags für die ausgewählten Dateien (liest nur, als Referenz):", + "fr_busy": "Benenne {0} Elemente um...\n\n{1}", + "fr_efail": "Umbenennen fehlgeschlagen:\n", + "fr_nchg": "{0} der neuen Namen wurden angepasst durch win und/oder no /\n\nMöchtest du mit diesen geänderten Namen fortfahren?", + + "fd_ok": "Löschen OK", + "fd_err": "Löschen fehlgeschlagen:\n", + "fd_none": "Nichts würde gelöscht; vielleicht durch die Serverkonfiguration blockiert (xbd)?", + "fd_busy": "Lösche {0} Elemente...\n\n{1}", + "fd_warn1": "Diese {0} Elemente LÖSCHEN?", + "fd_warn2": "Ich frage das letzte Mal! Was weg ist, ist weg. Keine Chance, das rückgängig zu machen. Löschen?", + + "fc_ok": "{0} Elemente ausgeschnitten", + "fc_warn": '{0} Elemente in die Zwischenablage kopiert\n\nAber: nur dieses Browsertab kann sie einfügen\n(da deine Auswahl so abartig riesig war)', + + "fcc_ok": "{0} Elemente in die Zwischenablage kopiert", + "fcc_warn": '{0} Elemente in die Zwischenablage kopiert\n\nAber: nur dieses Browsertab kann sie einfügen\n(da deine Auswahl so abartig riesig war)', + + "fp_apply": "Diese Namen verwenden", + "fp_ecut": "Kopiere erst ein paar Dateien / Ordner, um sie einzufügen\n\nTipp: Ausschneiden und Kopieren funktioniert über Browsertabs hinweg", + "fp_ename": "{0} Elemente konnten nicht verschoben werden, weil bereits andere Dateien mit diesen Namen existieren. Gib ihnen unten neue Namen um fortzufahren, oder lass das Feld leer zum Überspringen:", + "fcp_ename": "{0} Elemente konnten nicht kopiert werden, weil bereits andere Dateien mit diesen Namen existieren. Gib ihnen unten neue Namen um fortzufahren, oder lass das Feld leer zum Überspringen:", + "fp_emore": "Es gibt noch ein paar Dateinamen, die geändert werden müssen", + "fp_ok": "Verschieben OK", + "fcp_ok": "Kopieren OK", + "fp_busy": "Verschiebe {0} Elemente...\n\n{1}", + "fcp_busy": "Kopiere {0} Elemente...\n\n{1}", + "fp_err": "Verschieben fehlgeschlagen:\n", + "fcp_err": "Kopieren fehlgeschlagen:\n", + "fp_confirm": "Diese {0} Elemente hierher verschieben?", + "fcp_confirm": "Diese {0} Elemente hierher kopieren?", + "fp_etab": 'Konnte die Zwischenablage nicht vom anderen Browsertab lesen', + "fp_name": "Lade Datei von deinem Gerät hoch. Gib ihr einen Namen:", + "fp_both_m": '
Wähle, was eingefügt werden soll
Eingabe = {0} Dateien von «{1}» verschieben\nESC = {2} Dateien von deinem Gerät hochladen', + "fcp_both_m": '
Wähle, was eingefügt werden soll
Eingabe = {0} Dateien von «{1}» kopieren\nESC = {2} Dateien von deinem Gerät hochladen', + "fp_both_b": 'VerschiebenHochladen', + "fcp_both_b": 'KopierenHochladen', + + "mk_noname": "Tipp' mal vorher lieber einen Namen in das Textfeld links, bevor du das machst :p", + + "tv_load": "Textdatei wird geladen:\n\n{0}\n\n{1}% ({2} von {3} MiB geladen)", + "tv_xe1": "Konnte Textdatei nicht laden:\n\nFehler ", + "tv_xe2": "404, Datei nicht gefunden", + "tv_lst": "Liste der Textdateien in", + "tvt_close": "Zu Ordneransicht zurück$NHotkey: M (oder Esc)\">❌ Schliessen", + "tvt_dl": "Diese Datei herunterladen$NHotkey: Y\">💾 Herunterladen", + "tvt_prev": "Vorheriges Dokument zeigen$NHotkey: i\">⬆ vorh.", + "tvt_next": "Nächstes Dokument zeigen$NHotkey: K\">⬇ nächst.", + "tvt_sel": "Wählt diese Datei aus   ( zum Ausschneiden / Kopieren / Löschen / ... )$NHotkey: S\">ausw.", + "tvt_edit": "Datei im Texteditor zum Bearbeiten öffnen$NHotkey: E\">✏️ bearb.", + "tvt_tail": "Datei auf Veränderungen überwachen; Neue Zeilen werden in Echtzeit angezeigt\">📡 folgen", + "tvt_wrap": "Zeilenumbruch\">↵", + "tvt_atail": "Automatisch nach unten scrollen\">⚓", + "tvt_ctail": "Terminal-Farben dekodieren (ANSI Escape Codes)\">🌈", + "tvt_ntail": "Scrollback limitieren (Menge an Bytes an Text, die geladen bleiben sollen)", + + "m3u_add1": "Song wurde zur M3U-Playlist hinzugefügt", + "m3u_addn": "{0} Songs zur M3U-Playlist hinzugefügt", + "m3u_clip": "M3U-Playlist in die Zwischenablage kopiert\n\nDu solltest eine neue Datei mit dem Namen something.m3u erstellen und die Playlist da rein kopieren; damit wird die Playlist abspielbar", + + "gt_vau": "nur Ton abspielen, kein Video zeigen\">🎧", + "gt_msel": "Dateiauswahl aktivieren; STRG-klicke eine Datei zum überschreiben$N$N<em>wenn aktiv: Datei / Ordner doppelklicken zum Öffnen</em>$N$NHotkey: S\">multiselect", + "gt_crop": "Vorschaubilder mittig zuschneiden\">crop", + "gt_3x": "hochauflösende Vorschaubilder\">3x", + "gt_zoom": "zoom", + "gt_chop": "kürzen", + "gt_sort": "sortieren nach", + "gt_name": "Name", + "gt_sz": "Grösse", + "gt_ts": "Datum", + "gt_ext": "Typ", + "gt_c1": "Dateinamen mehr kürzen (weniger zeigen)", + "gt_c2": "Dateinamen weniger kürzen (mehr zeigen)", + + "sm_w8": "Suche ...", + "sm_prev": "Die Suchresultate gehören zu einer vorherigen Suchanfrage:\n ", + "sl_close": "Suchresultate schliessen", + "sl_hits": "Zeige {0} Treffer", + "sl_moar": "Mehr laden", + + "s_sz": "Grösse", + "s_dt": "Datum", + "s_rd": "Pfad", + "s_fn": "Name", + "s_ta": "Tags", + "s_ua": "up@", + "s_ad": "adv.", + "s_s1": "minimum MiB", + "s_s2": "maximum MiB", + "s_d1": "min. iso8601", + "s_d2": "max. iso8601", + "s_u1": "hochgeladen nach", + "s_u2": "und/oder vor", + "s_r1": "Pfad enthält   (Leerzeichen-separiert)", + "s_f1": "Name enthält   (negieren mit -nope)", + "s_t1": "Tags enthält   (^=start, end=$)", + "s_a1": "spezifische Metadaten-Eigenschaften", + + "md_eshow": "Kann nicht rendern ", + "md_off": "[📜readme] deaktiviert in [⚙️] -- Dokument versteckt", + + "badreply": "Hab die Antwort vom Server nicht verstanden. (badreply)", + + "xhr403": "403: Zugriff verweigert\n\nVersuche, F5 zu drücken. Vielleicht wurdest du abgemeldet.", + "xhr0": "Unbekannt (wahrschenlich Verbindung zum Server verloren oder der Server ist offline)", + "cf_ok": "Sorry dafür -- Der DD" + wah + "oS-Schutz hat angeschlagen.\n\nEs sollte in etwa 30 Sekunden weitergehen.\n\nFalls nichts passiert, drück' F5, um die Seite neuzuladen", + "tl_xe1": "Konnte Unterordner nicht auflisten:\n\nFehler ", + "tl_xe2": "404: Ordner nicht gefunden", + "fl_xe1": "Konnte Dateien in Ordner nicht auflisten:\n\nFehler ", + "fl_xe2": "404: Ordner nicht gefunden", + "fd_xe1": "Konnte Unterordner nicht erstellen:\n\nFehler ", + "fd_xe2": "404: Übergeordneter Ordner nicht gefunden", + "fsm_xe1": "Konnte Nachricht nicht senden:\n\nFehler ", + "fsm_xe2": "404: Übergeordneter Ordner nicht gefunden", + "fu_xe1": "Konnte unpost-Liste nicht laden:\n\nFehler ", + "fu_xe2": "404: Datei nicht gefunden??", + + "fz_tar": "Unkomprimierte GNU TAR-Datei (Linux / Mac)", + "fz_pax": "Unkomprimierte pax-format TAR-Datei (etwas langsamer)", //m + "fz_targz": "GNU-TAR mit gzip Level 3 Kompression$N$Nüblicherweise recht langsam,$Nbenutze stattdessen ein unkomprimiertes TAR", + "fz_tarxz": "GNU-TAR mit xz level 1 Kompression$N$Nüblicherweise recht langsam,$Nbenutze stattdessen ein unkomprimiertes TAR", + "fz_zip8": "ZIP mit UTF8-Dateinamen (könnte kaputt gehen auf Windows 7 oder älter)", + "fz_zipd": "ZIP mit traditionellen CP437-Dateinamen, für richtig alte Software", + "fz_zipc": "CP437 mit CRC32 früh berechnet,$Nfür MS-DOS PKZIP v2.04g (Oktober 1993)$N(braucht länger zum Verarbeiten, bevor der Download starten kann)", + + "un_m1": "Unten kannst du deine neusten Uploads löschen (oder Unvollständige abbrechen)", + "un_upd": "Neu laden", + "un_m4": "Oder die unten sichtbaren Dateien teilen:", + "un_ulist": "Anzeigen", + "un_ucopy": "Kopieren", + "un_flt": "Optionale Filter:  URL muss enthalten", + "un_fclr": "Filter löschen", + "un_derr": 'unpost-delete fehlgeschlagen:\n', + "un_f5": 'Etwas ist kaputt gegangen, versuche die Seite neuzuladen (drücke dazu F5)', + "un_uf5": "Sorry, aber du musst die Seite neuladen (z.B. in dem du F5 oder STRG-R drückst) bevor zu diesen Upload abbrechen kannst", + "un_nou": 'Warnung: Der Server ist grade zu beschäftigt, um unvollständige Uploads anzuzeigen; Drücke den "Neu laden"-Link in ein paar Sekunden', + "un_noc": 'Warnung: unpost von vollständig hochgeladenen Dateien ist über die Serverkonfiguration gesperrt', + "un_max": "Zeige die ersten 2000 Dateien (benutze Filter, um die gewünschten Dateien zu finden)", + "un_avail": "{0} zuletzt hochgeladene Dateien können gelöscht werden
{1} Unvollständige können abgebrochen werden", + "un_m2": "Sortiert nach Upload-Zeitpunkt; neuste zuerst:", + "un_no1": "Hoppala! Es gibt keine ausreichend aktuellen Uploads.", + "un_no2": "Pech gehabt! Kein Upload, der zu dem Filter passen würde, ist neu genug", + "un_next": "Lösche die nächsten {0} Dateien", + "un_abrt": "Abbrechen", + "un_del": "Löschen", + "un_m3": "Deine letzten Uploads werden geladen ...", + "un_busy": "Lösche {0} Dateien ...", + "un_clip": "{0} Links in die Zwischenablage kopiert", + + "u_https1": "für bessere Performance solltest du", + "u_https2": "auf HTTPS wechseln", + "u_https3": "", + "u_ancient": 'Dein Browser ist verdammt antik -- vielleicht solltest du stattdessen bup benutzen', + "u_nowork": "Benötigt Firefox 53+ oder Chrome 57+ oder iOS 11+", + "tail_2old": "Benötigt Firefox 105+ oder Chrome 71+ oder iOS 14.5+", + "u_nodrop": 'Dein Browser ist zu alt für Drag-and-Drop Uploads', + "u_notdir": "Das ist kein Ordner!\n\nDein Browser ist zu alt,\nversuch stattdessen dragdrop", + "u_uri": "Um Bilder per Drag-and-Drop aus anderen Browserfenstern hochzuladen,\nlass' sie bitte über dem grossen Upload-Button fallen", + "u_enpot": 'Zu Potato UI wechseln (kann Upload-Geschw. verbessern)', + "u_depot": 'Zu fancy UI wechseln (kann Upload-Geschw. verschlechtern)', + "u_gotpot": 'Wechsle zu Potato UI für verbesserte Upload-Geschwindigkeit,\n\nwenn du anderer Meinung bist, kannst du gerne zurück wechseln', + "u_pott": "

Dateien:   {0} fertig,   {1} fehlgeschlagen,   {2} in Bearbeitung,   {3} ausstehend

", + "u_ever": "Dies ist der Basic Uploader; up2k benötigt mind.
Chrome 21 // Firefox 13 // Edge 12 // Opera 12 // Safari 5.1", + "u_su2k": 'Dies ist der Basic Uploader; up2k ist besser', + "u_uput": 'Für Geschwindigkeit optimieren (Checksum überspringen)', + "u_ewrite": 'Du hast kein Schreibzugriff auf diesen Ordner', + "u_eread": 'Du hast kein Lesezugriff auf diesen Ordner', + "u_enoi": 'file-search ist in der Serverkonfiguration nicht aktiviert', + "u_enoow": "Überschreiben wird hier nicht funktionieren; benötige Lösch-Berechtigung", + "u_badf": 'Diese {0} Dateien (von insgesammt {1}) wurden übersprungen, wahrscheinlich wegen Dateisystem-Berechtigungen:\n\n', + "u_blankf": 'Diese {0} Dateien (von insgesammt {1}) sind leer; trotzdem hochladen?\n\n', + "u_applef": 'Diese {0} Dateien (von insgesammt {1}) sind möglicherweise unerwünscht;\nOK/Eingabe drücken, um die folgenden Dateien zu überspringen.\nDrücke Abbrechen/ESC um sie NICHT zu überspringen und diese AUCH HOCHZULADEN:\n\n', + "u_just1": '\nFunktioniert vielleicht besser, wenn du nur eine Datei auswählst', + "u_ff_many": "Falls du Linux / MacOS / Android benutzt, könnte Firefox mit dieser Menge an Dateien crashen!\nFalls das passiert, probier nochmal (oder benutz Chrome).", + "u_up_life": "Dieser Upload wird vom Server gelöscht\n{0} nachdem er abgeschlossen ist", + "u_asku": 'Diese {0} Dateien nach {1} hochladen', + "u_unpt": "Du kannst diesen Upload rückgängig machen mit dem 🧯 oben-links", + "u_bigtab": 'Versuche {0} Dateien anzuzeigen.\n\nDas könnte dein Browser crashen, bist du dir wirklich sicher?', + "u_scan": 'Scanne Dateien...', + "u_dirstuck": 'Ordner-Iterator blieb hängen beim Versuch, diese {0} Einträge zu lesen; überspringe:', + "u_etadone": 'Fertig ({0}, {1} Dateien)', + "u_etaprep": '(Upload wird vorbereitet)', + "u_hashdone": 'Hashing vollständig', + "u_hashing": 'Hash', + "u_hs": 'Wir schütteln uns die Hände ("handshaking")...', + "u_started": "Dateien werden hochgeladen; siehe [🚀]", + "u_dupdefer": "Duplikat; wird nach allen anderen Dateien verarbeitet", + "u_actx": "Klicke diesen Text um Performance-
Einbusen zu Vermeiden beim Wechsel auf andere Fenster/Tabs", + "u_fixed": "OK!  Habs repariert 👍", + "u_cuerr": "failed to upload chunk {0} of {1};\nprobably harmless, continuing\n\nfile: {2}", + "u_cuerr2": "server rejected upload (chunk {0} of {1});\nwill retry later\n\nfile: {2}\n\nerror ", + "u_ehstmp": "versuche nochmal; siehe unten-rechts", + "u_ehsfin": "Der Server hat die Anfrage zum Abschluss des Uploads abgelehnt; versuche nochmal...", + "u_ehssrch": "Der Server hat die Anfrage zur Suche abgelehnt; versuche nochmal...", + "u_ehsinit": "Der Server hat die Anfrage zum Start des Uploads abgelehnt; versuche nochmal...", + "u_eneths": "Netzwerkfehler beim Upload-Handshake; versuche nochmal...", + "u_enethd": "Netzwerkfehler beim Testen der Existenz des Ziels; versuche nochmal...", + "u_cbusy": "Der Server mag uns grade nicht mehr nach einem Netzwerkglitch, warte einen Moment...", + "u_ehsdf": "Server hat kein Speicherplatz mehr!\n\nwerde es erneut versuchen, falls jemand\ngenug Platz schafft um fortzufahren", + "u_emtleak1": "scheint, als ob dein Browser ein Memory Leak hätte;\nbitte", + "u_emtleak2": ' wechsle auf HTTPS (empfohlen) oder ', + "u_emtleak3": '', + "u_emtleakc": 'versuche folgendes:\nUploads werden etwas langsamer sein, aber man kann ja nicht alles haben.\nSorry für die Umstände !\n\nPS: Chrome v107 hat ein Bugfix dafür', + "u_emtleakf": 'versuche folgendes:\n\nPS: Firefox hat hoffentlich irgendwann ein Bugfix', + "u_s404": "nicht auf dem Server gefunden", + "u_expl": "erklären", + "u_maxconn": "die meisten Browser limitieren dies auf 6, aber Firefox lässt mehr zu unter connections-per-server in about:config", + "u_tu": '

WARNUNG: Turbo aktiviert,  Client könnte unvollständige Uploads verpassen und nicht wiederholen; siehe Turbo-Button Tooltip

', + "u_ts": '

WARNUNG: Turbo aktiviert,  Suchresultate können inkorrekt sein; siehe Turbo-Button Tooltip

', + "u_turbo_c": "Turbo deaktiviert in der Serverkonfiguration", + "u_turbo_g": "Turbo deaktiviert, da du keine Listen-Berechtigung\nauf diesem Volume hast", + "u_life_cfg": 'Autodelete nach min (or h)', + "u_life_est": 'Upload wird gelöscht ---', + "u_life_max": 'Dieser Ordner erzwingt eine\nmax Lebensdauer von {0}', + "u_unp_ok": 'unpost ist erlaubt für {0}', + "u_unp_ng": 'unpost wird NICHT erlaubt', + "ue_ro": 'Du hast nur Lese-Zugriff auf diesen Ordner\n\n', + "ue_nl": 'Du bist nicht angemeldet', + "ue_la": 'Du bist angemeldet als "{0}"', + "ue_sr": 'Du bist derzeit im Suchmodus\n\nWechsle zum Upload-Modus indem du auf die Lupe 🔎 klickst (neben dem grossen SUCHEN Button), und versuche den Upload nochmal.\n\nSorry', + "ue_ta": 'Versuche den Upload nochmal, sollte jetzt klappen', + "ue_ab": "Diese Datei wird gerade in einem anderen Ordner hochgeladen, dieser Upload muss zuerst abgeschlossen werden, bevor die Datei woanders hochgeladen werden kann.\n\nDu kannst den Upload abbrechen und vergessen mit dem 🧯 oben-links", + "ur_1uo": "OK: Datei erfolgreich hochgeladen", + "ur_auo": "OK: Alle {0} Dateien erfolgreich hochgeladen", + "ur_1so": "OK: Datei auf dem Server gefunden", + "ur_aso": "OK: Alle {0} Dateien auf dem Server gefunden", + "ur_1un": "Upload fehlgeschlagen, sorry", + "ur_aun": "Alle {0} Uploads fehlgeschlagen, sorry", + "ur_1sn": "Datei wurde NICHT auf dem Server gefunden", + "ur_asn": "Die {0} Dateien wurden NICHT auf dem Server gefunden", + "ur_um": "Fertig;\n{0} Uploads OK,\n{1} Uploads fehlgeschlagen, sorry", + "ur_sm": "Fertig;\n{0} Uploads gefunden auf dem Server,\n{1} Dateien NICHT gefunden auf dem Server", + + "lang_set": "Neuladen um Änderungen anzuwenden?", + }, + "fin": { + "tt": "Suomi", + + "cols": { + "c": "toimintopainikkeet", + "dur": "kesto", + "q": "laatu / bittinopeus", + "Ac": "äänikoodekki", + "Vc": "videokoodekki", + "Fmt": "formaatti / säiliö", + "Ahash": "äänen tarkistussumma", + "Vhash": "videon tarkistussumma", + "Res": "resoluutio", + "T": "tiedostotyyppi", + "aq": "äänenlaatu / bittinopeus", + "vq": "kuvalaatu / bittinopeus", + "pixfmt": "alinäytteistys / pikselirakenne", + "resw": "horisontaalinen resoluutio", + "resh": "vertikaalinen resoluutio", + "chs": "äänikanavat", + "hz": "näytteenottotaajuus" + }, + + "hks": [ + [ + "misc", + ["ESC", "sulje asioita"], + + "file-manager", + ["G", "vaihda lista/ruudukkonäkymään"], + ["T", "vaihda pienoiskuviin/kuvakkeisiin"], + ["⇧ A/D", "pienoiskuvien koko"], + ["ctrl-K", "poista valitut"], + ["ctrl-X", "siirrä valitut leikepöydälle"], + ["ctrl-C", "kopioi valitut leikepöydälle"], + ["ctrl-V", "siirrä tai kopioi tähän"], + ["Y", "lataa valitut"], + ["F2", "uudelleennimeä valitut"], + + "file-list-sel", + ["space", "vaihda tiedostonvalintatilaan"], + ["↑/↓", "siirrä valintaosoitinta"], + ["ctrl ↑/↓", "siirrä osoitinta ja näkymää"], + ["⇧ ↑/↓", "valitse edellinen/seuraava tiedosto"], + ["ctrl-A", "valitse kaikki tiedostot / kansiot"], + ], [ + "navigation", + ["B", "näytä linkkipolku"], + ["I/K", "siirry edelliseen/seuraavaan hakemistoon"], + ["M", "siirry ylähakemistoon/supista nykyinen hakemisto"], + ["V", "näytä kansiot/tekstitiedostot navigointipaneelissa"], + ["A/D", "navigointipaneelin koko"], + ], [ + "audio-player", + ["J/L", "edellinen/seuraava kappale"], + ["U/O", "kelaa 10s taaksepäin/eteenpäin"], + ["0..9", "siirry 0%..90%"], + ["P", "toista/pysäytä kappale"], + ["S", "valitse toistossa oleva kappale"], + ["Y", "lataa kappale"], + ], [ + "image-viewer", + ["J/L, ←/→", "edellinen/seuraava kuva"], + ["Home/End", "ensimmäinen/viimeinen kuva"], + ["F", "siirry koko näytön tilaan"], + ["R", "kierrä myötäpäivään"], + ["⇧ R", "kierrä vastapäivään"], + ["S", "valitse kuva"], + ["Y", "lataa kuva"], + ], [ + "video-player", + ["U/O", "kelaa 10s taaksepäin/eteenpäin"], + ["P/K/Space", "toista/pysäytä video"], + ["C", "jatka toistoa seuraavaan videoon"], + ["V", "toista uudelleen"], + ["M", "vaimenna"], + ["[ ja ]", "aseta videon uudelleentoistoväli"], + ], [ + "textfile-viewer", + ["I/K", "edellinen/seuraava tiedosto"], + ["M", "sulje tekstitiedosto"], + ["E", "muokkaa tekstitiedostoa"], + ["S", "valitse tiedosto (leikkausta/kopiointia/uudelleennimeämistä varten)"], + ] + ], + + "m_ok": "OK", + "m_ng": "Peruuta", + + "enable": "Aktivoi", + "danger": "HUOMIO!", + "clipped": "kopioitu leikepöydälle", + + "ht_s1": "sekunti", + "ht_s2": "sekuntia", + "ht_m1": "minuutti", + "ht_m2": "minuuttia", + "ht_h1": "tunti", + "ht_h2": "tuntia", + "ht_d1": "päivä", + "ht_d2": "päivää", + "ht_and": " ja ", + + "goh": "ohjauspaneeli", + "gop": 'viereinen hakemisto">edell', + "gou": 'ylempi hakemisto">ylös', + "gon": 'seuraava hakemisto">seur', + "logout": "Kirjaudu ulos ", + "access": " -oikeudet", + "ot_close": "sulje alavalikko", + "ot_search": "etsi tiedostoja ominaisuuksien, tiedostopolun tai -nimen, musiikkitägien tai näiden yhdistelmän perusteella$N$N<code>foo bar</code> = täytyy sisältää sekä «foo» että «bar»,$N<code>foo -bar</code> = täytyy sisältää «foo» mutta ei «bar»,$N<code>^yana .opus$</code> = alkaa «yana» ja on «opus»-tiedosto$N<code>"try unite"</code> = sisältää täsmälleen «try unite»$N$Npäivämäärän muoto on iso-8601, kuten$N<code>2009-12-31</code> tai <code>2020-09-12 23:30:00</code>", + "ot_unpost": "unpost: poista viimeaikaiset tai keskeytä keskeneräiset lataukset", + "ot_bup": "bup: tiedostojen 'perus'lähetysohjelma, tukee jopa netscape 4.0:aa", + "ot_mkdir": "mkdir: luo uusi hakemisto", + "ot_md": "new-md: luo uusi markdown-dokumentti", + "ot_msg": "msg: lähetä viesti palvelinlokiin", + "ot_mp": "mediasoittimen asetukset", + "ot_cfg": "asetukset", + "ot_u2i": 'up2k: lähetä tiedostoja (vaatii write-oikeudet) tai vaihda hakutilaan nähdäksesi, ovatko tiedostot jo olemassa jossain päin palvelinta$N$Nlatauksia voi jatkaa, ne ovat monisäikeistettyjä, ja tiedostojen aikaleimat säilytetään; nuijii prosessoria enemmän kuin [🎈]  (peruslatausohjelma)

tiedostojen lähetyksen aikana tämä kuvake muuttuu kertoo lähetyksen edistymisestilanteen!', + "ot_u2w": 'up2k: lähetä tiedostoja jatkamistoiminnolla (voit sulkea selaimen ja vetää samat tiedostot selainikkunaan myöhemmin)$N$monisäikeistetty, ja tiedostojen aikaleimat säilyvät; nuijii prosessoria enemmän kuin [🎈]  (peruslatausohjelma)

tiedostojen lähetyksen aikana tämä kuvake muuttuu kertoo lähetyksen edistymisestilanteen!', + "ot_noie": 'Suosittelemme käyttämään uudempaa selainta.', + + "ab_mkdir": "luo hakemisto", + "ab_mkdoc": "luo markdown-tiedosto", + "ab_msg": "lähetä viesti palvelinlokiin", + + "ay_path": "siirry kansioihin", + "ay_files": "siirry tiedostoihin", + + "wt_ren": "uudelleennimeä valitut kohteet$NPikanäppäin: F2", + "wt_del": "poista valitut kohteet$NPikanäppäin: ctrl-K", + "wt_cut": "siirrä valitut kohteet leikepöydälle <small>(siirtääksesi ne muualle)</small>$NPikanäppäin: ctrl-X", + "wt_cpy": "kopioi valitut kohteet leikepöydälle$N(liittääksesi ne muualle)$NPikanäppäin: ctrl-C", + "wt_pst": "liitä aiemmin leikatut / kopioidut valinnat$NPikanäppäin: ctrl-V", + "wt_selall": "valitse kaikki tiedostot$NPikanäppäin: ctrl-A (kun tiedosto on kohdistettu)", + "wt_selinv": "valitse vastakkaiset tiedostot", + "wt_zip1": "lataa tämä kansio pakattuna", + "wt_selzip": "lataa valitut kohteet pakattuna", + "wt_seldl": "lataa valitut kohteet paketoimatta$NPikanäppäin: Y", + "wt_npirc": "kopioi kappaletiedot IRC-muotoilulla", + "wt_nptxt": "kopioi kappaletiedot ilman muotoilua", + "wt_m3ua": "lisää m3u-soittolistaan (klikkaa 📻kopioi myöhemmin)", + "wt_m3uc": "kopioi m3u-soittolista leikepöydälle", + "wt_grid": "vaihda ruudukko- ja listanäkymän välillä$NPikanäppäin: G", + "wt_prev": "edellinen kappale$NPikanäppäin: J", + "wt_play": "toista / pysäytä$NPikanäppäin: P", + "wt_next": "seuraava kappale$NPikanäppäin: L", + + "ul_par": "rinnakkaisten latausten lkm:", + "ut_rand": "satunnaisgeneroidut tiedostonimet", + "ut_u2ts": "kopioi viimeksi muokattu aikaleima$Ntiedostojärjestelmästäsi palvelimelle\">📅", + "ut_ow": "korvaa olemassa olevat tiedostot palvelimella?$N🛡️: ei koskaan (luo sen sijaan uuden tiedostonimen)$N🕒: korvaa jos palvelintiedosto on vanhempi kuin omasi$N♻️: korvaa aina jos tiedostot ovat erilaisia", + "ut_mt": "jatka muiden tiedostojen tiivisteiden laskemista latauksen aikana$N$kannattanee poistaa käytöstä, mikäli prosessori tai kovalevy on vanhempaa mallia", + "ut_ask": 'kysy vahvistusta ennen latauksen aloittamista">💭', + "ut_pot": "paranna latausnopeutta hitailla laitteilla$Ntekemällä käyttöliittymäästä vähemmän monimutkaisen", + "ut_srch": "lataamisen sijaan tarkista, ovatko tiedostot jo $N olemassa palvelimella (käy läpi kaikki hakemistot, joihin sinulla on read-oikeudet)", + "ut_par": "keskeytä lataukset asettamalla se 0:aan$N$Nnosta, jos yhteytesi on hidas tai viive on suuri$N$Npidä se 1:ssä lähiverkossa tai jos palvelimen kovalevy on pullonkaula", + "ul_btn": "vedä tiedostoja / kansioita
tähän (tai napsauta tätä)", + "ul_btnu": "L A T A A", + "ul_btns": "E T S I", + + "ul_hash": "tiiviste", + "ul_send": "lähetä", + "ul_done": "valmis", + "ul_idle1": "ei latauksia jonossa", + "ut_etah": "keskimääräinen <em>tiivisteiden lasku</em>nopeus ja arvioitu aika valmistumiseen", + "ut_etau": "keskimääräinen <em>lataus</em>nopeus ja arvioitu aika valmistumiseen", + "ut_etat": "keskimääräinen <em>kokonais</em>nopeus ja arvioitu aika valmistumiseen", + + "uct_ok": "onnistui", + "uct_ng": "ei-hyvä: epäonnistui / hylätty / ei löydy", + "uct_done": "ok ja ng yhdistettynä", + "uct_bz": "laskee tiivisteitä tai lataa", + "uct_q": "tyhjäkäynnillä, odottaa", + + "utl_name": "tiedostonimi", + "utl_ulist": "lista", + "utl_ucopy": "kopioi", + "utl_links": "linkit", + "utl_stat": "tila", + "utl_prog": "edistyminen", + + // keep short: + "utl_404": "404", + "utl_err": "VIRHE", + "utl_oserr": "Käyttöjärjestelmävirhe", + "utl_found": "löytyi", + "utl_defer": "lykkää", + "utl_yolo": "YOLO", + "utl_done": "valmis", + + "ul_flagblk": "tiedostot lisättiin jonoon
mutta toisen selainvälilehden up2k on kiireinen,
joten odotetaan sen valmistumista ensin", + "ul_btnlk": "palvelinkonfiguraatio on lukinnut tämän kytkimen tähän tilaan", + + "udt_up": "Lataa", + "udt_srch": "Etsi", + "udt_drop": "pudota se tähän", + + "u_nav_m": '
selvä, mitäs sulla on?
Enter = Tiedostoja (yksi tai useampi)\nESC = Yksi kansio (mukaan lukien alikansiot)', + "u_nav_b": 'TiedostojaYksi kansio', + + "cl_opts": "kytkimet", + "cl_themes": "teema", + "cl_langs": "kieli", + "cl_ziptype": "kansion lataus", + "cl_uopts": "up2k-kytkimet", + "cl_favico": "favicon", + "cl_bigdir": "suuret hakemistot", + "cl_hsort": "#lajittelu", + "cl_keytype": "sävellajin notaatio", + "cl_hiddenc": "piilotetut sarakkeet", + "cl_hidec": "piilota", + "cl_reset": "palauta", + "cl_hpick": "napauta sarakeotsikoita piilottaaksesi alla olevassa taulukossa", + "cl_hcancel": "sarakkeiden piilotus peruttu", + + "ct_grid": '田 RUUDUKKO', + "ct_ttips": '◔ ◡ ◔">ℹ️ ammattilaisvinkit', + "ct_thumb": 'RUUDUKKOnäkymässä, vaihda kuvakkeihin tai pienoiskuviin$NPikanäppäin: T">🖼️ pienoiskuvat', + "ct_csel": 'käytä CTRL ja SHIFT tiedostojen valintaan RUUDUKKOnäkymässä">val', + "ct_ihop": 'kun kuvakatselin suljetaan, vieritä alas viimeksi katsottuun tiedostoon">g⮯', + "ct_dots": 'näytä piilotetut tiedostot (jos palvelin sallii)">piilotiedostot', + "ct_qdel": 'tiedostoja poistaessa, kysy vahvistusta vain kerran">qdel', + "ct_dir1st": 'lajittele hakemistot ennen tiedostoja">📁 ensin', + "ct_nsort": 'luonnollinen lajittelu (tiedostonimille jotka ovat numeroalkuisia)">nsort', + "ct_utc": 'näytä kaikki aikaleimat UTC-ajassa">UTC', + "ct_readme": 'näytä README.md hakemistolistauksissa">📜 readme', + "ct_idxh": 'näytä index.html hakemistolistan sijasta">htm', + "ct_sbars": 'näytä vierityspalkit">⟊', + + "cut_umod": "jos tiedosto on jo olemassa palvelimella, päivitä palvelimen viimeksi muokattu aikaleima vastaamaan paikallista tiedostoasi (vaatii write- ja delete-oikeudet)\">re📅", + + "cut_turbo": "yolo-painike, ET todennäköisesti halua ottaa tätä käyttöön:$N$Nkäytä tätä jos latasit valtavan määrän tiedostoja ja jouduit käynnistämään uudelleen jostain syystä, ja haluat jatkaa latausta ASAP$N$Ntämä korvaa tiivistetarkistuksen yksinkertaisella "onko tällä sama tiedostokoko palvelimella?" joten jos tiedoston sisältö on erilainen sitä EI ladata$N$Nsinun pitäisi poistaa tämä käytöstä kun lataus on valmis, ja sitten "ladata" samat tiedostot uudelleen antaaksesi asiakkaan varmistaa ne\">turbo", + + "cut_datechk": "ei vaikutusta ellei turbo-painike ole käytössä$N$Nvähentää yolo-tekijää hieman; tarkistaa vastaavatko tiedostojen aikaleimat palvelimella omia$N$Npitäisi teoriassa napata useimmat keskeneräiset / vioittuneet lataukset, mutta ei ole korvike varmistuskierrokselle turbo poistettuna käytöstä jälkeenpäin\">päiväys-tark", + + "cut_u2sz": "kunkin lähetyspalan koko (MiB:ssä); suuret arvot lentävät paremmin atlantin yli. kokeile pieniä arvoja erittäin heikoilla yhteyksillä", + + "cut_flag": "varmista että vain yksi välilehti lataa kerrallaan $N -- muissa välilehdissä täytyy olla tämä käytössä myös $N -- vaikuttaa vain saman verkkotunnuksen välilehtiin", + + "cut_az": "lähetä tiedostot aakkosjärjestyksessä, eikä pienin-tiedosto-ensiksi$N$Naakkosjärjestys voi tehdä helpommaksi silmäillä jos jokin meni vikaan palvelimella, mutta se tekee latauksesta hieman hitaamman kuitu- ja lähiverkossa", + + "cut_nag": "käyttöjärjestelmäilmoitus kun lataus valmistuu$N(vain jos selain tai välilehti ei ole aktiivinen)", + "cut_sfx": "äänivaroitus kun lataus valmistuu$N(vain jos selain tai välilehti ei ole aktiivinen)", + + "cut_mt": "monisäikeistä tiedostojen tiivistysarvojen laskeminen$N$Ntämä käyttää web-workereitä ja vaatii$Nenemmän RAM-muistia (jopa 512 MiB ekstraa)$N$Ntekee https:n 30% nopeammaksi, http:n 4.5x nopeammaksi\">mt", + + "cut_wasm": "käytä wasm:ia selaimen sisäänrakennetun tiivistäjän sijaan; parantaa nopeutta chrome-pohjaisissa selaimissa mutta lisää prosessorikuormaa, ja monissa vanhemmissa chrome-versioissa on bugeja jotka saavat selaimen kuluttamaan kaiken RAM-muistin ja kaatumaan jos tämä on käytössä\">wasm", + + "cft_text": "favicon-teksti (tyhjennä ja päivitä poistaaksesi käytöstä)", + "cft_fg": "edustaväri", + "cft_bg": "taustaväri", + + "cdt_lim": "tiedostojen enimmäismäärä näytettäväksi kansiossa", + "cdt_ask": "sivun lopussa,$Nsen sijaan että lataa automaattisesti lisää tiedostoja,$Nkysy mitä tehdä", + "cdt_hsort": "kuinka monta lajittelusääntöä (<code>,sorthref</code>) sisällyttää media-URL:eihin. Tämän asettaminen nollaan jättää myös huomioimatta media-linkeissä sisällytetyt lajittelusäännöt kun napsautat niitä", + + "tt_entree": "näytä navigointipaneeli$NPikanäppäin: B", + "tt_detree": "näytä linkkipolku$NPikanäppäin: B", + "tt_visdir": "näytä valittu kansio", + "tt_ftree": "vaihda linkkipolku- / tekstitiedostonäkymään$NPikanäppäin: V", + "tt_pdock": "näytä yläkansiot telakoitussa paneelissa ylhäällä", + "tt_dynt": "kasvata automaattisesti hakemistosyvyyden kasvaessa", + "tt_wrap": "rivitys", + "tt_hover": "paljasta ylivuotavat rivit leijutettaessa$N( rikkoo vierityksen ellei hiiri $N  ole vasemmassa marginaalissa )", + + "ml_pmode": "kansion lopussa...", + "ml_btns": "komennot", + "ml_tcode": "transkoodaa", + "ml_tcode2": "transkoodaa muotoon", + "ml_tint": "sävy", + "ml_eq": "taajuuskorjain", + "ml_drc": "dynaaminen alueen kompressori", + + "mt_loop": "toista samaa kappaletta\">🔁", + "mt_one": "lopeta yhden kappaleen jälkeen\">1️⃣", + "mt_shuf": "satunnaistoisto\">🔀", + "mt_aplay": "automaattitoisto jos linkissä jolla pääsit palvelimelle oli kappale-ID$N$Ntämän poistaminen käytöstä pysäyttää myös sivun URL:n päivittämisen kappale-ID:lla musiikkia toistettaessa, estääksesi automaattitoiston jos nämä asetukset menetetään mutta URL säilyy\">a▶", + "mt_preload": "aloita seuraavan kappaleen lataaminen lähellä loppua, mahdollistaen saumattoman toiston\">esilataus", + "mt_prescan": "siirry seuraavaan kansioon ennen viimeisen kappaleen$Nloppumista, pitäen verkkoselaimen tyytyväisenä$Njotta se ei pysäytä toistoa\">nav", + "mt_fullpre": "yritä esiladata koko kappale;$N✅ ota käyttöön heikoilla yhteyksillä,$N❌ poista käytöstä hitailla yhteyksillä\">täysi", + "mt_fau": "puhelimissa: estä musiikin pysähtyminen jos seuraava kappale ei esilataudu tarpeeksi nopeasti (voi aiheuttaa ongelmia kappaletietojen näyttämisessä)\">☕️", + "mt_waves": "aaltomuoto-hakupalkki:$Nnäytä äänenvahvuus selaimessa\">~s", + "mt_npclip": "näytä painikkeet parhaillaan soivan kappaleen leikepöydälle kopioimiseen\">/np", + "mt_m3u_c": "näytä painikkeet valittujen$Nkappaleiden kopioimiseen m3u8-soittolistana leikepöydälle\">📻", + "mt_octl": "käyttöjärjestelmäintegraatio (medianäppäimet / osd)\">os-ctl", + "mt_oseek": "salli haku käyttöjärjestelmäintegraation kautta$N$Nhuom: joissakin laitteissa (iPhonet),$Ntämä korvaa seuraava-kappale-painikkeen\">kelaus", + "mt_oscv": "näytä albumin kansi osd:ssä\">taide", + "mt_follow": "pidä soiva kappale näkyvissä\">🎯", + "mt_compact": "kompaktit säätimet\">⟎", + "mt_uncache": "tyhjennä välimuisti  (kokeile tätä jos selaimesi välimuistissa on$Nrikkinäinen kopio kappaleesta)\">uncache", + "mt_mloop": "toista avoinna olevaa hakemistoa loputtomasti\">🔁 silmukka", + "mt_mnext": "lataa seuraava kansio ja jatka\">📂 seuraava", + "mt_mstop": "pysäytä toisto\">⏸ pysäytä", + "mt_cflac": "muunna flac / wav opus-muotoon\">flac", + "mt_caac": "muunna aac / m4a opus-muotoon\">aac", + "mt_coth": "muunna kaikki muut paitsi mp3 opus-muotoon\">muut", + "mt_c2opus": "paras valinta pöytäkoneille, kannettaville, androidille\">opus", + "mt_c2owa": "opus-weba, iOS 17.5:lle ja uudemmille\">owa", + "mt_c2caf": "opus-caf, iOS 11:lle - 17:lle\">caf", + "mt_c2mp3": "käytä tätä erittäin vanhoissa laitteissa\">mp3", + "mt_c2ok": "hienoa, hyvä valinta", + "mt_c2nd": "tuo ei ole suositeltu formaatti laitteellesi, mutta tee miten lystäät", + "mt_c2ng": "laitteesi ei näytä tukevan tätä formaattia, mutta yritetään nyt silti", + "mt_xowa": "iOS:ssä on bugeja jotka estävät taustatoiston tällä formaatilla; käytä caf:ia tai mp3:a sen sijaan", + "mt_tint": "taustan taso (0-100) liukupalkissa$Ntehden puskuroinnista vähemmän häiritsevän", + "mt_eq": "aktivoi taajuuskorjaimen ja vahvistussäätimen;$N$Nvahvistus <code>0</code> = normaali 100% äänenvoimakkuus (muokkaamaton)$N$Nleveys <code>1  </code> = normaali stereo (muokkaamaton)$Nleveys <code>0.5</code> = 50% vasen-oikea ristisyöttö$Nleveys <code>0  </code> = mono$N$Nvahvistus <code>-0.8</code> & leveys <code>10</code> = laulun poisto :^)$N$Nequalizerin käyttöönotto tekee saumattomista albumeista täysin saumattomia, joten jätä se päälle kaikilla arvoilla nollassa (paitsi leveys = 1) jos välität siitä", + "mt_drc": "aktivoi dynaamisen alueen kompressorin (äänenvoimakkuuden tasoittaja / tiiliseinättäjä); ottaa myös käyttöön EQ:n tasapainottamaan spagettia, joten aseta kaikki EQ-kentät paitsi 'leveys' 0:aan jos et halua sitä$N$Nalentaa äänenvoimakkuutta KYNNYS dB:n yläpuolella; jokaisesta SUHDE dB:stä KYNNYKSEN yli tulee 1 dB ulos, joten oletusarvot kynnys -24 ja suhde 12 tarkoittaa ettei sen pitäisi koskaan tulla kovempaa kuin -22 dB ja on turvallista nostaa equalizerin vahvistus 0.8:aan, tai jopa 1.8:aan ATK 0:lla ja valtavalla RLS:llä kuten 90 (toimii vain firefoxissa; RLS on max 1 muissa selaimissa)$N$N(katso wikipedia, he selittävät sen paljon paremmin)", + + "mb_play": "toista", + "mm_hashplay": "soita tämä äänitiedosto?", + "mm_m3u": "paina Enter/OK Toistaaksesi\npaina ESC/Peruuta Muokataksesi", + "mp_breq": "tarvitset firefox 82+ tai chrome 73+ tai iOS 15+", + "mm_bload": "ladataan...", + "mm_bconv": "muunnetaan muotoon {0}, odota...", + "mm_opusen": "selaimesi ei voi toistaa aac / m4a -tiedostoja;\ntranskoodaus opukseen on nyt käytössä", + "mm_playerr": "toisto epäonnistui: ", + "mm_eabrt": "Toistoyritys peruttiin", + "mm_enet": "Internet-yhteytesi on epävakaa", + "mm_edec": "Tämä tiedosto on väitetysti vioittunut??", + "mm_esupp": "Selaimesi ei ymmärrä tätä äänimuotoa", + "mm_eunk": "Tuntematon virhe", + "mm_e404": "Kappaletta ei voitu toistaa; virhe 404: Tiedostoa ei löydy.", + "mm_e403": "Kappaletta ei voitu toistaa; virhe 403: Pääsy kielletty.\n\nKokeile painaa F5 päivittääksesi, ehkä kirjauduit ulos", + "mm_e500": "Kappaletta ei voitu toistaa; virhe 500: Tarkista palvelinlokit.", + "mm_e5xx": "Kappaletta ei voitu toistaa; palvelinvirhe ", + "mm_nof": "ei löydy enempää äänitiedostoja lähistöltä", + "mm_prescan": "Etsitään musiikkia toistettavaksi seuraavaksi...", + "mm_scank": "Löytyi seuraava kappale:", + "mm_uncache": "välimuisti tyhjennetty; kaikki kappaleet ladataan uudelleen seuraavalla toistolla", + "mm_hnf": "tuota kappaletta ei enää ole olemassa", + +" im_hnf": "tuota kuvaa ei enää ole olemassa", + + "f_empty": 'tämä kansio on tyhjä', + "f_chide": 'tämä piilottaa sarakkeen «{0}»\n\nvoit palauttaa sarakkeet asetuksista', + "f_bigtxt": "tämä tiedosto on {0} Mt kokoinen -- näytetäänkö silti tekstinä?", + "f_bigtxt2": "näytetäänkö vain tiedoston loppu? tämä myös mahdollistaa seuraamisen/tailing, näyttäen uudet tekstirivit reaaliaikaisesti", + "fbd_more": '
näytetään {0} / {1} tiedostoa; näytä {2} tai näytä kaikki
', + "fbd_all": '
näytetään {0} / {1} tiedostoa; näytä kaikki
', + "f_anota": "vain {0} / {1} kohdetta valittiin;\nvalitaksesi koko kansion, vieritä ensin loppuun", + + "f_dls": 'nykyisen kansion tiedostolinkit on\nvaihdettu latauslinkeiksi', + + "f_partial": "Ladataksesi turvallisesti tiedoston joka on parhaillaan latautumassa, klikkaa tiedostoa jolla on sama nimi mutta ilman .PARTIAL päätettä. Paina PERUUTA tai Escape tehdäksesi tämän.\n\nOK / Enter painaminen sivuuttaa tämän varoituksen ja jatkaa .PARTIAL väliaikaistiedoston lataamista, mikä todennäköisesti antaa sinulle vioittunutta dataa.", + + "ft_paste": "liitä {0} kohdetta$NPikanäppäin: ctrl-V", + "fr_eperm": 'ei voida nimetä uudelleen:\nsinulla ei ole “move”-oikeutta tässä kansiossa', + "fd_eperm": 'ei voida poistaa:\nsinulla ei ole “delete” oikeutta tässä kansiossa', + "fc_eperm": 'ei voida leikata:\nsinulla ei ole “move” oikeutta tässä kansiossa', + "fp_eperm": 'ei voida liittää:\nsinulla ei ole “write” oikeutta tässä kansiossa', + "fr_emore": "valitse vähintään yksi kohde uudelleennimettäväksi", + "fd_emore": "valitse vähintään yksi kohde poistettavaksi", + "fc_emore": "valitse vähintään yksi kohde leikattavaksi", + "fcp_emore": "valitse vähintään yksi kohde kopioitavaksi leikepöydälle", + + "fs_sc": "jaa kansio jossa olet", + "fs_ss": "jaa valitut tiedostot", + "fs_just1d": "et voi valita useampaa kuin yhtä kansiota,\ntai sekoittaa tiedostoja ja kansioita yhdessä valinnassa", + "fs_abrt": "❌ keskeytä", + "fs_rand": "🎲 joku.nimi", + "fs_go": "✅ luo share", + "fs_name": "nimi", + "fs_src": "lähde", + "fs_pwd": "salasana", + "fs_exp": "vanheneminen", + "fs_tmin": "min", + "fs_thrs": "tuntia", + "fs_tdays": "päivää", + "fs_never": "ikuinen", + "fs_pname": "valinnainen linkin nimi; on satunnainen jos tyhjä", + "fs_tsrc": "jaettava tiedosto tai kansio", + "fs_ppwd": "valinnainen salasana", + "fs_w8": "luodaan sharea...", + "fs_ok": "paina Enter/OK lisätäksesi leikepöydälle\npaina ESC/Cancel sulkeaksesi", + + "frt_dec": "saattaa korjata joitakin rikkinäisiä tiedostonimiä\">url-decode", + "frt_rst": "palauta muokatut tiedostonimet takaisin alkuperäisiksi\">↺ palauta", + "frt_abrt": "keskeytä ja sulje tämä ikkuna\">❌ peruuta", + "frb_apply": "UUDELLEENNIMEÄ", + "fr_adv": "erä / liitännäistiedot / kaava uudelleennimeäminen\">lisäasetukset", + "fr_case": "isot ja pienet kirjaimet erottava regex\">kirjainkoko", + "fr_win": "windows-yhteensopivat nimet; korvaa <>:"\\|?* japanilaisilla leveillä merkeillä\">win", + "fr_slash": "korvaa / merkillä joka ei aiheuta uusien kansioiden luomista\">ei /", + "fr_re": "regex hakukuvio jota käytetään alkuperäisiin tiedostonimiin; kaappausryhmiin voi viitata alla olevassa muotoilukentässä kuten <code>(1)</code> ja <code>(2)</code> ja niin edelleen", + "fr_fmt": "foobar2000 innoittama:$N<code>(title)</code> korvataan kappaleen nimellä,$N<code>[(artist) - ](title)</code> sivuuttaa [tämän] osan jos artisti on tyhjä$N<code>$lpad((tn),2,0)</code> ", + "fr_pdel": "poista", + "fr_pnew": "tallenna nimellä", + "fr_pname": "anna nimi uudelle esiasetuksellesi", + "fr_aborted": "keskeytetty", + "fr_lold": "vanha nimi", + "fr_lnew": "uusi nimi", + "fr_tags": "valittujen tiedostojen tagit (vain luku, viitetarkoituksiin):", + "fr_busy": "nimetään uudelleen {0} kohdetta...\n\n{1}", + "fr_efail": "uudelleennimeäminen epäonnistui:\n", + "fr_nchg": "{0} uusista nimistä muutettiin win ja/tai ei / vuoksi\n\nJatketaanko näillä muutetuilla uusilla nimillä?", + + "fd_ok": "poisto OK", + "fd_err": "poisto epäonnistui:\n", + "fd_none": "mitään ei poistettu; ehkä palvelimen asetukset estivät (xbd)?", + "fd_busy": "poistetaan {0} kohdetta...\n\n{1}", + "fd_warn1": "POISTA nämä {0} kohdetta?", + "fd_warn2": "Viimeinen varoitus! Haluatko varmasti poistaa?", + + "fc_ok": "siirettiin {0} kohdetta leikepöydälle", + "fc_warn": 'siirettiin {0} kohdetta leikepöydälle\n\nmutta: vain tämä selain-välilehti voi liittää ne\n(koska valinta on niin valtavan suuri)', + + "fcc_ok": "kopioitiin {0} kohdetta leikepöydälle", + "fcc_warn": 'kopioitiin {0} kohdetta leikepöydälle\n\nmutta: vain tämä selain-välilehti voi liittää ne\n(koska valinta on niin valtavan suuri)', + + "fp_apply": "käytä näitä nimiä", + "fp_ecut": "leikkaa tai kopioi ensin joitakin tiedostoja / kansioita liitettäväksi / siirrettäväksi\n\nhuom: voit leikata / liittää eri selain-välilehtien välillä", + "fp_ename": "{0} kohdetta ei voida siirtää tänne koska nimet ovat jo käytössä. Anna niille uudet nimet alla jatkaaksesi, tai tyhjennä nimi ohittaaksesi ne:", + "fcp_ename": "{0} kohdetta ei voida kopioida tänne koska nimet ovat jo käytössä. Anna niille uudet nimet alla jatkaaksesi, tai tyhjennä nimi ohittaaksesi ne:", + "fp_emore": "tiedostonimien törmäyksiä on vielä korjaamatta", + "fp_ok": "siirto OK", + "fcp_ok": "kopiointi OK", + "fp_busy": "siirretään {0} kohdetta...\n\n{1}", + "fcp_busy": "kopioidaan {0} kohdetta...\n\n{1}", + "fp_err": "siirto epäonnistui:\n", + "fcp_err": "kopiointi epäonnistui:\n", + "fp_confirm": "siirrä nämä {0} kohdetta tänne?", + "fcp_confirm": "kopioi nämä {0} kohdetta tänne?", + "fp_etab": 'leikepöydän lukeminen toisesta selain-välilehdestä epäonnistui', + "fp_name": "ladataan tiedostoa laitteeltasi. Anna sille nimi:", + "fp_both_m": '
valitse mitä liittää
Enter = Siirrä {0} tiedostoa kohteesta «{1}»\nESC = Lataa {2} tiedostoa laitteeltasi', + "fcp_both_m": '
valitse mitä liittää
Enter = Kopioi {0} tiedostoa kohteesta «{1}»\nESC = Lataa {2} tiedostoa laitteeltasi', + "fp_both_b": 'SiirräLähetä', + "fcp_both_b": 'KopioiLähetä', + + "mk_noname": "kirjoita nimi vasemmalla olevaan tekstikenttään ennen kuin teet tuon :p", + + "tv_load": "Ladataan tekstidokumenttia:\n\n{0}\n\n{1}% ({2} / {3} Mt ladattu)", + "tv_xe1": "tekstitiedoston lataaminen epäonnistui:\n\nvirhe ", + "tv_xe2": "404, tiedostoa ei löydy", + "tv_lst": "tekstitiedostojen lista kansiossa", + "tvt_close": "palaa kansionäkymään$NPikanäppäin: M (tai Esc)\">❌ sulje", + "tvt_dl": "lataa tämä tiedosto$NPikanäppäin: Y\">💾 lataa", + "tvt_prev": "näytä edellinen dokumentti$NPikanäppäin: i\">⬆ edell", + "tvt_next": "näytä seuraava dokumentti$NPikanäppäin: K\">⬇ seur", + "tvt_sel": "valitse tiedosto   ( leikkausta / kopiointia / poistoa / ... varten )$NPikanäppäin: S\">val", + "tvt_edit": "avaa tiedosto tekstieditorissa$NPikanäppäin: E\">✏️ muokkaa", + "tvt_tail": "seuraa tiedoston muutoksia; näytä uudet rivit reaaliaikaisesti\">📡 seuraa", + "tvt_wrap": "rivitys\">↵", + "tvt_atail": "lukitse vieritys sivun alaosaan\">⚓", + "tvt_ctail": "dekoodaa terminaalin värit (ansi escape koodit)\">🌈", + "tvt_ntail": "vieritysbufferin raja (kuinka monta tavua tekstiä pidetään ladattuna)", + + "m3u_add1": "kappale lisätty m3u soittolistaan", + "m3u_addn": "{0} kappaletta lisätty m3u soittolistaan", + "m3u_clip": "m3u soittolista nyt kopioitu leikepöydälle\n\nsinun tulisi luoda uusi tekstitiedosto nimeltä jotain.m3u ja liittää soittolista siihen dokumenttiin; tämä tekee siitä soitettavan", + + "gt_vau": "älä näytä videoita, toista vain ääni\">🎧", + "gt_msel": "ota käyttöön tiedostojen valinta; ctrl-klikkaa tiedostoa ohittaaksesi$N$N<em>kun aktiivinen: tuplaklikkaa tiedostoa / kansiota avataksesi sen</em>$N$NPikanäppäin: S\">monivalinta", + "gt_crop": "keskitä-rajaa pienoiskuvat\">rajaa", + "gt_3x": "korkearesoluutioiset pienoiskuvat\">3x", + "gt_zoom": "zoomaa", + "gt_chop": "pilko", + "gt_sort": "järjestä", + "gt_name": "nimi", + "gt_sz": "koko", + "gt_ts": "päiväys", + "gt_ext": "tyyppi", + "gt_c1": "rajaa tiedostonimiä enemmän (näytä vähemmän)", + "gt_c2": "rajaa tiedostonimiä vähemmän (näytä enemmän)", + + "sm_w8": "haetaan...", + "sm_prev": "alla olevat hakutulokset ovat edellisestä hausta:\n ", + "sl_close": "sulje hakutulokset", + "sl_hits": "näytetään {0} osumaa", + "sl_moar": "lataa lisää", + + "s_sz": "koko", + "s_dt": "päiväys", + "s_rd": "polku", + "s_fn": "nimi", + "s_ta": "tagit", + "s_ua": "ylös@", + "s_ad": "edist.", + "s_s1": "minimi Mt", + "s_s2": "maksimi Mt", + "s_d1": "min. iso8601", + "s_d2": "maks. iso8601", + "s_u1": "ladattu jälkeen", + "s_u2": "ja/tai ennen", + "s_r1": "polku sisältää   (välilyönnillä erotetuttuina)", + "s_f1": "nimi sisältää   (negatoi käyttämällä -nope)", + "s_t1": "tagit sisältää   (^=alku, loppu=$)", + "s_a1": "tietyt metadatan ominaisuudet", + + "md_eshow": "ei voida renderoida ", + "md_off": "[📜readme] poistettu käytöstä [⚙️] -- dokumentti piilotettu", + + "badreply": "Palvelimen vastauksen jäsentäminen epäonnistui.", + + "xhr403": "403: Pääsy kielletty\n\nkokeile painaa F5, ehkä sinut kirjattiin ulos", + "xhr0": "tuntematon (todennäköisesti yhteys palvelimeen katosi, tai palvelin on pois päältä)", + "cf_ok": "sori siitä -- DD" + wah + "oS suojaus aktivoitui\n\nasioiden pitäisi jatkua noin 30 sekunnissa\n\njos mitään ei tapahdu, paina F5 ladataksesi sivun uudelleen", + "tl_xe1": "alikansioiden listaaminen epäonnistui:\n\nvirhe ", + "tl_xe2": "404: Kansiota ei löydy", + "fl_xe1": "kansion tiedostojen listaaminen epäonnistui:\n\nvirhe ", + "fl_xe2": "404: Kansiota ei löydy", + "fd_xe1": "alikansion luominen epäonnistui:\n\nvirhe ", + "fd_xe2": "404: Yläkansiota ei löydy", + "fsm_xe1": "viestin lähettäminen epäonnistui:\n\nvirhe ", + "fsm_xe2": "404: Yläkansiota ei löydy", + "fu_xe1": "unpost-listan lataaminen palvelimelta epäonnistui:\n\nvirhe ", + "fu_xe2": "404: Tiedostoa ei löydy??", + + "fz_tar": "pakkaamaton gnu-tar tiedosto (linux / mac)", + "fz_pax": "pakkaamaton pax-formaatin tar (hitaampi)", + "fz_targz": "gnu-tar gzip tason 3 pakkauksella$N$NTämä on yleensä hyvin hidasta, $Nkäytä pakkamatonta tar:ia sen sijaan", + "fz_tarxz": "gnu-tar xz tason 1 pakkauksella$N$NTämä on yleensä hyvin hidasta, $Nkäytä pakkamatonta tar:ia sen sijaan", + "fz_zip8": "zip utf8-tiedostonimillä (suattaapi olla epävakaa windows 7:ssa ja vanhemmissa)", + "fz_zipd": "zip perinteisillä cp437 tiedostonimillä esihistoriallisille ohjelmistoille", + "fz_zipc": "cp437, jossa crc32 laskettu aikaisin,$NMS-DOS PKZIP v2.04g:lle (lokakuu 1993)$N(kestää kauemmin käsitellä ennen latauksen alkua)", + + "un_m1": "voit poistaa viimeaikaiset latauksesi (tai keskeyttää keskeneräiset) alla", + "un_upd": "päivitä", + "un_m4": "tai jaa alla näkyvät tiedostot:", + "un_ulist": "näytä", + "un_ucopy": "kopioi", + "un_flt": "valinnainen suodatin:  URL:n täytyy sisältää", + "un_fclr": "tyhjennä suodatin", + "un_derr": 'unpost-poisto epäonnistui:\n', + "un_f5": 'jotain hajosi, kokeile päivitystä tai paina F5', + "un_uf5": "pahoittelen mutta sinun täytyy päivittää sivu (esimerkiksi painamalla F5 tai CTRL-R) ennen kuin tämä lataus voidaan keskeyttää", + "un_nou": 'varoitus: palvelin liian kiireinen näyttääkseen keskeneräiset lataukset; klikkaa "päivitä" linkkiä hetken kuluttua', + "un_noc": 'varoitus: täysin ladattujen tiedostojen unpost ei ole käytössä/sallittu palvelimen asetuksissa', + "un_max": "näytetään ensimmäiset 2000 tiedostoa (käytä suodatinta)", + "un_avail": "{0} viimeaikaista latausta voidaan poistaa
{1} keskeneräistä voidaan keskeyttää", + "un_m2": "järjestetty latausajan mukaan; viimeisimmät ensin:", + "un_no1": "hupsis! yksikään lataus ei ole riittävän tuore", + "un_no2": "hupsis! yksikään tuota suodatinta vastaava lataus ei ole riittävän tuore", + "un_next": "poista seuraavat {0} tiedostoa alla", + "un_abrt": "keskeytä", + "un_del": "poista", + "un_m3": "ladataan viimeaikana lähettämiäsi tiedostoja...", + "un_busy": "poistetaan {0} tiedostoa...", + "un_clip": "{0} linkkiä kopioitu leikepöydälle", + + "u_https1": "sinun kannattaisi", + "u_https2": "vaihtaa https:ään", + "u_https3": "paremman suorituskyvyn vuoksi", + "u_ancient": 'selaimesi on ns. vaikuttavan ikivanha -- kannattais varmaan käyttää bup:ia tän sijaan', + "u_nowork": "tarvitaan firefox 53+ tai chrome 57+ tai iOS 11+", + "tail_2old": "tarvitaan firefox 105+ tai chrome 71+ tai iOS 14.5+", + "u_nodrop": 'selaimesi on liian vanha vedä-ja-pudota lataamiseen', + "u_notdir": "tuo ei ole hakemisto!\n\nselaimesi on liian vanha,\nkokeile sen sijaan 'vedä-pudota'-tekniikkaa.", + "u_uri": "'vedä-pudottaaksesi' kuvia muista selainikkunoista,\npudota se isoon latausnapppiin", + "u_enpot": 'vaihda peruna UI:hin (voi parantaa latausnopeutta)', + "u_depot": 'vaihda ylelliseen UI:hin (voi vähentää latausnopeutta)', + "u_gotpot": 'vaihdetaan peruna UI:hin paremman latausnopeuden vuoksi,\n\ntee miten lystäät, jos ei kelpaa!', + "u_pott": "

tiedostot:   {0} valmis,   {1} epäonnistui,   {2} kiireinen,   {3} jonossa

", + "u_ever": "tämä on peruslatain; up2k tarvitsee vähintään
chrome 21 // firefox 13 // edge 12 // opera 12 // safari 5.1", + "u_su2k": 'tämä on peruslatain; up2k on parempi', + "u_uput": 'optimoi nopeuteen (ohita tarkistussumma)', + "u_ewrite": 'sinulla ei ole move-oikeutta tähän kansioon', + "u_eread": 'sinulla ei ole read-oikeutta tähän kansioon', + "u_enoi": 'tiedostohaku ei ole käytössä palvelimen asetuksissa', + "u_enoow": "ylikirjoitus ei toimi täällä; tarvitaan “Delete”-oikeus", + "u_badf": 'Nämä {0} tiedostoa ({1} yhteensä) ohitettiin, mahdollisesti tiedostojärjestelmän oikeuksien vuoksi:\n\n', + "u_blankf": 'Nämä {0} tiedostoa ({1} yhteensä) ovat tyhjiä; ladataanko ne silti?\n\n', + "u_applef": 'Nämä {0} tiedostoa ({1} yhteensä) ovat todennäköisesti ei-toivottuja;\nPaina OK/Enter OHITTAAKSESI seuraavat tiedostot,\nPaina Cancel/ESC jos ET halua sulkea pois, ja LATAA nekin:\n\n', + "u_just1": '\nEhkä toimii paremmin jos valitset vain yhden tiedoston', + "u_ff_many": "jos käytät Linux / MacOS / Android, niin tämä määrä tiedostoja saattaa kaataa Firefoxin!\njos niin käy, kokeile uudelleen (tai käytä Chromea).", + "u_up_life": "Tämä lataus poistetaan palvelimelta\n{0} sen valmistumisen jälkeen", + "u_asku": 'lataa nämä {0} tiedostoa kohteeseen {1}', + "u_unpt": "voit perua / poistaa tämän latauksen käyttämällä vasemmalla ylhäällä olevaa 🧯", + "u_bigtab": 'näytetään {0} tiedostoa\n\ntämä voi kaataa selaimesi, oletko varma?', + "u_scan": 'Skannataan tiedostoja...', + "u_dirstuck": 'hakemistoiteraattori jumittui yrittäessään käyttää seuraavia {0} kohdetta; ohitetaan:', + "u_etadone": 'Valmis ({0}, {1} tiedostoa)', + "u_etaprep": '(valmistellaan latausta)', + "u_hashdone": 'hajautus valmis', + "u_hashing": 'hajautus', + "u_hs": 'kätellään...', + "u_started": "tiedostoja ladataan nyt; tsekkaa [🚀]", + "u_dupdefer": "duplikaatti; käsitellään kaikkien muiden tiedostojen jälkeen", + "u_actx": "klikkaa tätä tekstiä estääksesi suorituskyvyn
heikkenemisen vaihtaessasi muihin ikkunoihin/välilehtiin", + "u_fixed": "OK!  Hommat hoidossa 👍", + "u_cuerr": "chunk {0} / {1} lataus epäonnistui;\ntuskin haittaa, jatketaan\n\ntiedosto: {2}", + "u_cuerr2": "palvelin hylkäsi latauksen (chunk {0} / {1});\nyritetään myöhemmin uudelleen\n\ntiedosto: {2}\n\nvirhe ", + "u_ehstmp": "yritetään uudelleen; katso oikealta alhaalta", + "u_ehsfin": "palvelin hylkäsi pyynnön viimeistellä lataus; yritetään uudelleen...", + "u_ehssrch": "palvelin hylkäsi pyynnön suorittaa haku; yritetään uudelleen...", + "u_ehsinit": "palvelin hylkäsi pyynnön aloittaa lataus; yritetään uudelleen...", + "u_eneths": "verkkovirhe latauksen kättelyssä; yritetään uudelleen...", + "u_enethd": "verkkovirhe kohteen olemassaolon testauksessa; yritetään uudelleen...", + "u_cbusy": "odotetaan palvelimen luottavan meihin taas verkko-ongelman jälkeen...", + "u_ehsdf": "palvelimen levytila loppui!\n\nyritetään jatkuvasti, siinä tapauksessa että joku\nvapauttaa tarpeeksi tilaa jatkamiseen", + "u_emtleak1": "näyttää siltä että selaimessasi saattaa olla muistivuoto;\nole hyvä ja", + "u_emtleak2": ' vaihda https:ään (suositeltu) tai ', + "u_emtleak3": ' ', + "u_emtleakc": 'kokeile seuraavaa:\nLataukset ovat hieman hitaampia, minkäs teet.\nSori siitä!\n\nPS: chrome v107 sisältää bugfixin tätä varten', + "u_emtleakf": 'kokeile seuraavaa:\n\nPS: firefox toivottavasti saa kerättyä itsensä kasaan jossain vaiheessa', + "u_s404": "ei löydy palvelimelta", + "u_expl": "selitä", + "u_maxconn": "useimmat selaimet rajoittavat tämän 6:een, mutta firefox antaa nostaa sitä connections-per-server asetuksella about:config:issa", + "u_tu": '

VAROITUS: turbo päällä,  asiakasohjelma ei välttämättä huomaa jatkaa keskeneräisiä latauksia; katso turbo-napin vihje

', + "u_ts": '

VAROITUS: turbo päällä,  hakutulokset voivat olla vääriä; katso turbo-napin vihje

', + "u_turbo_c": "turbo on poistettu käytöstä palvelimen asetuksissa", + "u_turbo_g": "poistetaan turbo käytöstä koska sinulla ei ole\nhakemistolistausoikeuksia tässä asemassa", + "u_life_cfg": 'automaattinen poisto min kuluttua (tai tuntia)', + "u_life_est": 'lataus poistetaan ---', + "u_life_max": 'tämä kansio pakottaa\nmaksimi elinajan {0}', + "u_unp_ok": 'unpost on sallittu {0}', + "u_unp_ng": 'unpost EI ole sallittu', + "ue_ro": 'sinulla on vain read-oikeus tähän kansioon\n\n', + "ue_nl": 'et ole tällä hetkellä kirjautunut sisään', + "ue_la": 'olet tällä hetkellä kirjautunut sisään nimellä "{0}"', + "ue_sr": 'olet tällä hetkellä tiedostohaku-tilassa\n\nvaihda lataus-tilaan klikkaamalla suurennuslasia 🔎 (suuren HAKU napin vieressä), ja yritä latausta uudelleen\n\npahoittelen', + "ue_ta": 'yritä latausta uudelleen, sen pitäisi toimia nyt', + "ue_ab": "tätä tiedostoa ladataan jo toiseen kansioon, ja se lataus täytyy suorittaa loppuun ennen kuin tiedostoa voidaan ladata muualle.\n\nVoit keskeyttää ja unohtaa alkuperäisen latauksen käyttämällä vasemmalla ylhäällä olevaa 🧯", + "ur_1uo": "OK: Tiedosto ladattu onnistuneesti", + "ur_auo": "OK: Kaikki {0} tiedostoa ladattu onnistuneesti", + "ur_1so": "OK: Tiedosto löytyi palvelimelta", + "ur_aso": "OK: Kaikki {0} tiedostoa löytyi palvelimelta", + "ur_1un": "Lataus epäonnistui, pahoittelen", + "ur_aun": "Kaikki {0} latausta epäonnistui, pahoittelen", + "ur_1sn": "Tiedostoa EI löytynyt palvelimelta", + "ur_asn": "{0} tiedostoa EI löytynyt palvelimelta", + "ur_um": "Valmis;\n{0} latausta OK,\n{1} latausta epäonnistui, pahoittelen", + "ur_sm": "Valmis;\n{0} tiedostoa löytyi palvelimelta,\n{1} tiedostoa EI löytynyt palvelimelta", + + "lang_set": "päivitetäänkö sivu muutoksen voimaansaattamiseksi?", + }, + "rus": { + "tt": "Русский", + + "cols": { + "c": "кнопки действий", + "dur": "длительность", + "q": "качество / битрейт", + "Ac": "аудио кодек", + "Vc": "видео кодек", + "Fmt": "формат / контейнер", + "Ahash": "контрольная сумма аудио", + "Vhash": "контрольная сумма видео", + "Res": "разрешение", + "T": "тип файла", + "aq": "качество аудио / битрейт", + "vq": "качество видео / битрейт", + "pixfmt": "сабсемплинг / пиксельный формат", + "resw": "горизонтальное разрешение", + "resh": "вертикальное разрешение", + "chs": "аудио каналы", + "hz": "частота дискретизации" + }, + + "hks": [ + [ + "разное", + ["ESC", "закрыть всякие штуки"], + + "файловый менеджер", + ["G", "переключиться между списком / плиткой"], + ["T", "переключиться между миниатюрами / иконками"], + ["⇧ A/D", "размер миниатюры"], + ["ctrl-K", "удалить выделенное"], + ["ctrl-X", "вырезать выделенное в буфер"], + ["ctrl-C", "копировать выделенное в буфер"], + ["ctrl-V", "вставить (переместить/копировать) сюда"], + ["Y", "скачать выделенное"], + ["F2", "переименовать выделенное"], + + "выделение файлов", + ["пробел", "выделить/снять выделение с текущего файла"], + ["↑/↓", "двигать курсор"], + ["ctrl ↑/↓", "двигать курсор и скроллить"], + ["⇧ ↑/↓", "выделить предыдущий/следующий файл"], + ["ctrl-A", "выделить все файлы и папки"], + ], [ + "навигация", + ["B", "показать/скрыть панель навигации"], + ["I/K", "предыдущая/следующая папка"], + ["M", "перейти на уровень выше (или свернуть текущую папку)"], + ["V", "переключиться между папками / текстовыми файлами в панели навигации"], + ["A/D", "уменьшить/увеличить панель навигации"], + ], [ + "аудиоплеер", + ["J/L", "предыдущий/следующий трек"], + ["U/O", "перемотать на 10 секунд назад/вперёд"], + ["0..9", "перемотать на 0%..90%"], + ["P", "играть/пауза (или подгрузить трек)"], + ["S", "выделить текущий трек"], + ["Y", "скачать трек"], + ], [ + "просмотрщик изображений", + ["J/L, ←/→", "предыдущее/следующее изображение"], + ["Home/End", "первое/последнее изображение"], + ["F", "развернуть на полный экран"], + ["R", "повернуть по часовой стрелке"], + ["⇧ R", "повернуть против часовой стрелки"], + ["S", "выделить изображение"], + ["Y", "скачать изображение"], + ], [ + "видеоплеер", + ["U/O", "перемотать на 10 секунд назад/вперёд"], + ["P/K/Space", "играть/пауза"], + ["C", "продолжить проигрывать следующее"], + ["V", "повтор"], + ["M", "выключить звук"], + ["[ and ]", "задать интервал повтора"], + ], [ + "просмотрщик текстовых файлов", + ["I/K", "предыдущий/следующий файл"], + ["M", "закрыть файл"], + ["E", "отредактировать файл"], + ["S", "выделить файл"], + ] + ], + + "m_ok": "OK", + "m_ng": "Отмена", + + "enable": "Включить", + "danger": "ВНИМАНИЕ", + "clipped": "скопировано в буфер обмена", + + "ht_s1": "секунда", + "ht_s2": "секунды", + "ht_m1": "минута", + "ht_m2": "минуты", + "ht_h1": "час", + "ht_h2": "часы", + "ht_d1": "день", + "ht_d2": "дни", + "ht_and": " и ", + + "goh": "панель управления", + "gop": 'предыдущая папка">пред', + "gou": 'родительская папка">вверх', + "gon": 'следующая папка">след', + "logout": "Выйти ", + "access": " доступ", + "ot_close": "закрыть подменю", + "ot_search": "искать файлы по атрибутам, пути / имени, музыкальным тегам или любой другой комбинации из следующих конструкций$N$N<code>foo bar</code> = обязано содержать «foo» И «bar»,$N<code>foo -bar</code> = обязано содержать «foo», но не «bar»,$N<code>^yana .opus$</code> = начинается с «yana» и имеет расширение «opus»$N<code>"try unite"</code> = содержит именно «try unite»$N$Nформат времени задаётся по стандарту iso-8601, например$N<code>2009-12-31</code> или <code>2020-09-12 23:30:00</code>", + "ot_unpost": "unpost: удалить ваши недавние загрузки и отменить незавершённые", + "ot_bup": "bup: легковесный загрузчик файлов, поддерживает даже netscape 4.0", + "ot_mkdir": "mkdir: создать новую папку", + "ot_md": "new-md: создать новый markdown-документ", + "ot_msg": "msg: отправить сообщение в лог сервера", + "ot_mp": "настройка медиаплеера", + "ot_cfg": "остальные настройки", + "ot_u2i": 'up2k: загрузить файлы (если имеется доступ к записи) или переключиться в режим поиска$N$Nзагрузки являются возобновляемыми и многопоточными, а даты изменения файлов сохраняются в процессе, но этот метод использует больше ресурсов процессора, чем [🎈]  (легковесный загрузчик)

во время загрузки эта иконка превращается в индикатор!', + "ot_u2w": 'up2k: загрузить файлы с поддержкой возобновления (закиньте те же файлы после перезапуска браузера)$N$Nподдерживается многопоточность, даты изменения файлов сохраняются в процессе, но этот метод использует больше ресурсов процессора, чем [🎈]  (легковесный загрузчик)

во время загрузки эта иконка превращается в индикатор!', + "ot_noie": 'Пожалуйста, используйте Chrome / Firefox / Edge', + + "ab_mkdir": "создать папку", + "ab_mkdoc": "создать markdown-документ", + "ab_msg": "отправить сообщение в лог сервера", + + "ay_path": "перейти к папкам", + "ay_files": "перейти к файлам", + + "wt_ren": "переименовать выделенные файлы$NГорячая клавиша: F2", + "wt_del": "удалить выделенные файлы$NГорячая клавиша: ctrl-K", + "wt_cut": "вырезать выделенные файлы <small>(затем вставить куда-то в другое место)</small>$NГорячая клавиша: ctrl-X", + "wt_cpy": "копировать выделенные файлы в буфер$N(чтобы вставить их куда-то ещё)$NГорячая клавиша: ctrl-C", + "wt_pst": "вставить ранее вырезанный / скопированный файл$NГорячая клавиша: ctrl-V", + "wt_selall": "выделить все файлы$NГорячая клавиша: ctrl-A (когда выделен хотя бы один файл)", + "wt_selinv": "инвертировать выделение", + "wt_zip1": "скачать эту папку как архив", + "wt_selzip": "скачать выделенные файлы как архив", + "wt_seldl": "скачать выделенные файлы по-отдельности$NГорячая клавиша: Y", + "wt_npirc": "копировать информацию о треке в формате irc", + "wt_nptxt": "копировать информацию о треке обычным текстом", + "wt_m3ua": "добавить в плейлист m3u (нажмите 📻коп. в конце)", + "wt_m3uc": "копировать плейлист m3u в буфер обмена", + "wt_grid": "переключить между сеткой / списком$NГорячая клавиша: G", + "wt_prev": "предыдущий трек$NГорячая клавиша: J", + "wt_play": "играть / пауза$NГорячая клавиша: P", + "wt_next": "следующий трек$NГорячая клавиша: L", + + "ul_par": "параллельные загрузки:", + "ut_rand": "случайные имена файлов", + "ut_u2ts": "копировать время последнего изменения$Nиз вашей файловой системы на сервер\">📅", + "ut_ow": "перезаписывать существующие файлы на сервере?$N🛡️: нет (для повторяющихся файлов будут создаваться новые имена)$N🕒: перезаписать файлы с датой изменения старее, чем у загружаемых$N♻️: всегда перезаписывать (если файлы различаются по содержанию)", + "ut_mt": "продолжать хешировать другие файлы во время загрузки$N$Nесть смысл отключить при медленном диске или процессоре", + "ut_ask": 'требовать подтверждения перед началом загрузки">💭', + "ut_pot": "улучшить скорость загрузки на слабых устройства$Nс помощью упрощения интерфейса", + "ut_srch": "не загружать, а проверять, существуют ли данные файлы $N на сервере (проверка всех доступных вам папок)", + "ut_par": "при 0 загрузка встанет на паузу$N$Nследует повысить, если ваше подключение медленное$N$Nоставьте 1, если используется локальная сеть или диск сервера медленный", + "ul_btn": "отпустите файлы / папки
здесь (или нажмите)", + "ul_btnu": "З А Г Р У З И Т Ь", + "ul_btns": "И С К А Т Ь", + + "ul_hash": "хеш", + "ul_send": "отправка", + "ul_done": "готово", + "ul_idle1": "нет загрузок в очереди", + "ut_etah": "средняя скорость <em>хеширования</em> и примерное время до завершения", + "ut_etau": "средняя скорость <em>загрузки</em> и примерное время до завершения", + "ut_etat": "средняя <em>общая</em> скорость и примерное время до завершения", + + "uct_ok": "успешно завершены", + "uct_ng": "ошибки / отказы / не найдены", + "uct_done": "готово (ok и ng вместе)", + "uct_bz": "хешируются или загружаются", + "uct_q": "в очереди", + + "utl_name": "имя файла", + "utl_ulist": "список", + "utl_ucopy": "копировать", + "utl_links": "ссылки", + "utl_stat": "статус", + "utl_prog": "прогресс", + + // keep short: + "utl_404": "404", + "utl_err": "ОШИБКА", + "utl_oserr": "ошибка ОС", + "utl_found": "найдено", + "utl_defer": "отложить", + "utl_yolo": "турбо", + "utl_done": "готово", + + "ul_flagblk": "файлы были добавлены в очередь,
однако в другой вкладке уже есть активная загрузка через up2k,
поэтому ожидаем её завершения", + "ul_btnlk": "настройки сервера запрещают изменение состояния этой опции", + + "udt_up": "Загрузить", + "udt_srch": "Поиск", + "udt_drop": "отпустите здесь", + + "u_nav_m": '
лады, что там у вас?
Enter = Файлы (один или больше)\nESC = Одна папка (с учётом подпапок)', + "u_nav_b": 'ФайлыОдна папка', + + "cl_opts": "переключатели", + "cl_themes": "тема", + "cl_langs": "язык", + "cl_ziptype": "архивация папок", + "cl_uopts": "опции up2k", + "cl_favico": "иконка", + "cl_bigdir": "бол. папки", + "cl_hsort": "#сорт.", + "cl_keytype": "схема горячих клавиш", + "cl_hiddenc": "скрытые столбцы", + "cl_hidec": "скрыть", + "cl_reset": "сбросить", + "cl_hpick": "нажмите на заголовки столбцов, чтобы скрыть их в таблице ниже", + "cl_hcancel": "скрытие столбца отменено", + + "ct_grid": '田 сетка', + "ct_ttips": '◔ ◡ ◔">ℹ️ подсказки', + "ct_thumb": 'переключение между иконками и миниатюрами в режиме сетки$NГорячая клавиша: T">🖼️ миниат.', + "ct_csel": 'держите CTRL или SHIFT для выделения файлов в режиме сетки">выбор', + "ct_ihop": 'показывать последний открытый файл после закрытия просмотрщика изображений">g⮯', + "ct_dots": 'показывать скрытые файлы (если есть доступ)">скрыт.', + "ct_qdel": 'спрашивать подтверждение только один раз перед удалением файлов">быстр. удал.', + "ct_dir1st": 'разместить папки над файлами">📁 сверху', + "ct_nsort": 'сортировка по числам$N(например, файл с >code<2>/code< в начале названия идёт перед >code<11>/code<)">нат. сорт.', + "ct_utc": 'используйте UTC для всех временных меток">UTC', //m + "ct_readme": 'показывать содержимое README.md в описании папки">📜 ридми', + "ct_idxh": 'показывать страницу index.html в текущей папке вместо интерфейса">htm', + "ct_sbars": 'показывать полосы прокрутки">⟊', + + "cut_umod": "если файл уже существует на сервере, обновить время последнего изменения на сервере в соответствии с локальным файлом (требуются права write+delete)\">перенос 📅", + + "cut_turbo": "используйте эту функцию С ОСТОРОЖНОСТЬЮ:$N$Nпригодится в случае, если была прервана загрузка большого количества файлов, и вы хотите возобновить её как можно быстрее$N$Nпроверка файлов по хешу заменяется на простой алгоритм: "если размер файла отличается - тогда загрузить", но содержание файлов не сравнивается$N$Nследует отключить эту функцию после окончания загрузки, а затем "загрузить" те же файлы заново, чтобы валидировать их\">турбо", + + "cut_datechk": "работает только при включённой кнопке "турбо"$N$Nчуть-чуть повышает надёжность турбо-загрузок с помощью сверки дат изменений между файлами на сервере и вашими$N$Nв теории достаточно для проверки большинства незавершённых / повреждённых загрузок, но не является альтернативой валидации файлов после турбо-загрузки\">провер. дат", + + "cut_u2sz": "размер (в МиБ) каждой загружаемой части; большие значения показывают лучшие результаты для дальних соединений. Если подключение нестабильное, попробуйте значение пониже", + + "cut_flag": "разрешить одновременную загрузку только из одной вкладки за раз $N -- обязательно включить эту опцию в остальных вкладках $N -- работает только в пределах одного домена", + + "cut_az": "загружать файлы в алфавитном порядке вместо "от меньшего к большему"$N$Nэто позволит проще отследить проблемы во время загрузки, но скорость слегка ниже на очень быстрых соединениях (например, в локальной сети)", + + "cut_nag": "системное уведомление по завершении загрузки$N(только при неактивной вкладке браузера)", + "cut_sfx": "звуковое уведомление по завершении загрузки$N(только при неактивной вкладке браузера)", + + "cut_mt": "использовать многопоточность для ускорения хеширования$N$Nиспользует Web Worker'ы и требует больше памяти (до 512 МиБ)$N$Nускоряет https на 30%, http - в 4,5 раз\">мп", + + "cut_wasm": "использовать модуль WASM вместо встроенной в браузер функции хеширования; ускоряет процесс в браузерах на основе Chromium, но увеличивает нагрузку на процессор. Старые версии Chrome содержат баги, которые заполняют всю оперативную память и крашат браузер, когда включена эта опция\">wasm", + + "cft_text": "текст для иконки (очистите поле и перезагрузите страницу для применения)", + "cft_fg": "цвет текста", + "cft_bg": "цвет фона", + + "cdt_lim": "максимальное количество файлов для показа в папке", + "cdt_ask": "внизу страницы спрашивать о действии вместо автоматической загрузки следующих файлов", + "cdt_hsort": "сколько правил сортировки (<code>,sorthref</code>) включать в адрес страницы. Если значение равно 0, по нажатии на ссылки будут игнорироваться правила, включённые в них", + + "tt_entree": "показать панель навигации$NГорячая клавиша: B", + "tt_detree": "скрыть панель навигации$NГорячая клавиша: B", + "tt_visdir": "прокрутить до выделенной папки", + "tt_ftree": "переключить между иерархией и списком текстовых файлов$NГорячая клавиша: V", + "tt_pdock": "закрепить родительские папки сверху панели", + "tt_dynt": "автоматическое расширение панели", + "tt_wrap": "перенос слов", + "tt_hover": "раскрывать обрезанные строки при наведении$N( ломает скроллинг, если $N  курсор не в пустоте слева )", + + "ml_pmode": "в конце папки...", + "ml_btns": "команды", + "ml_tcode": "транскодировать", + "ml_tcode2": "транскод. в", + "ml_tint": "затемн.", + "ml_eq": "эквалайзер", + "ml_drc": "компрессор", + + "mt_loop": "повторять один трек\">🔁", + "mt_one": "остановить после этого трека\">1️⃣", + "mt_shuf": "перемешать треки во всех папках\">🔀", + "mt_aplay": "автоматически играть треки по нажатии на ссылки с их ID$N$Nпри отключении адрес сайта также перестанет обновляться в соответствии с текущим треком\">a▶", + "mt_preload": "подгружать следующий трек перед концом текущего для бесшовного переключения\">предзагр.", + "mt_prescan": "переходить в следующую папку перед окончанием последнего трека$Nне даёт браузеру прервать следующий плейлист\">нав.", + "mt_fullpre": "подгружать следующий трек целиком;$N✅ полезно при нестабильном подключении,$N❌ при медленной скорости лучше выключить\">цел.", + "mt_fau": "для телефонов: начинать следующий трек сразу, даже если он не успел подгрузиться целиком (может сломать отображение тегов)\">☕️", + "mt_waves": "визуализация:$Nпоказывать волну громкости на полосе воспроизведения\">~", + "mt_npclip": "показать кнопки копирования для текущего трека\">/np", + "mt_m3u_c": "показать кнопки копирования для выделенных треков$Nв формате плейлистов m3u8\">📻", + "mt_octl": "интеграция с ОС (поддержка медиа-клавиш и музыкальных виджетов)\">интегр.", + "mt_oseek": "позволить перематывать треки через системные виджеты$N$Nвнимание: на некоторых устройствах (iPhone)$Nэто заменит кнопку следующего трека\">перемотка", + "mt_oscv": "показывать картинки альбомов в виджетах\">арт", + "mt_follow": "держать фокус на играющем треке\">🎯", + "mt_compact": "компактный плеер\">⟎", + "mt_uncache": "очистить кеш  (если браузер кешировал повреждённый$Nтрек и отказывается его запускать)\">уд. кеш", + "mt_mloop": "повторять треки в папке\">🔁 цикл", + "mt_mnext": "загрузить следующую папку и продолжить в ней\">📂 след.", + "mt_mstop": "приостановить воспроизведение\">⏸ стоп", + "mt_cflac": "конвертировать flac / wav в opus\">flac", + "mt_caac": "конвертировать aac / m4a в opus\">aac", + "mt_coth": "конвертировать всё остальное (кроме mp3) в opus\">др.", + "mt_c2opus": "лучший вариант для компьютеров и устройств на Android\">opus", + "mt_c2owa": "opus-weba, для iOS 17.5 и выше\">owa", + "mt_c2caf": "opus-caf, для iOS 11-17\">caf", + "mt_c2mp3": "для очень старых устройств\">mp3", + "mt_c2ok": "хороший выбор", + "mt_c2nd": "это не рекомендованный вариант формата для вашего устройства, но сойдёт", + "mt_c2ng": "не похоже, что ваше устройство поддерживает этот формат, но давайте попробуем и узнаем наверняка", + "mt_xowa": "в iOS есть баги, препятствующие фоновому воспроизведению этого формата. Пожалуйста, используйте caf или mp3", + "mt_tint": "непрозрачность фона (0-100) на полосе воспроизведения$N$Nделает буферизацию менее отвлекающей", + "mt_eq": "включить эквалайзер$N$Nboost <code>0</code> = стандартная громкость$N$Nwidth <code>1  </code> = обычное стерео$Nwidth <code>0.5</code> = микширование левого и правого каналов на 50%$Nwidth <code>0  </code> = моно$N$Nboost <code>-0.8</code> и width <code>10</code> = удаление голоса :^)$N$Nвключённый эквалайзер полностью убирает задержку между треками, поэтому следует его включить со всеми значениями на 0 (кроме width = 1), если вам нужно бесшовное воспроизведение", + "mt_drc": "включить компрессор; также включит эквалайзер для баланса вселенной, так что выставьте всё на 0 кроме width, если он вам не нужен$N$Nпонижает громкость при волне выше значения dB в tresh; каждый dB в ratio равен одному dB на выходе, так что стандартные значения tresh = -24 и ratio = 12 сделают так, что звук никогда не будет громче -22 dB. При таком раскладе можно поставить boost в эквалайзере на 0.8 или даже 1.8 при значении atk = 0 и огромном rls вроде 90 (работает только в Firefox, rls не может быть выше 1 в других браузерах)$N$N(загляните в википедию, там всё объяснено подробнее)", + + "mb_play": "играть", + "mm_hashplay": "воспроизвести этот музыкальный файл?", + "mm_m3u": "нажмите Enter/OK, чтобы играть\nнажмите ESC/Отмена, чтобы редактировать", + "mp_breq": "требуется Firefox 82+, Chrome 73+ или iOS 15+", + "mm_bload": "загружаю...", + "mm_bconv": "конвертирую в {0}, подождите...", + "mm_opusen": "ваш браузер не может воспроизводить файлы aac / m4a;\nвключено транскодирование в opus", + "mm_playerr": "ошибка воспроизведения: ", + "mm_eabrt": "Попытка воспроизведения была отменена", + "mm_enet": "Ваше подключение нестабильно", + "mm_edec": "Этот файл, возможно, повреждён??", + "mm_esupp": "Ваш браузер не распознаёт этот аудио-формат", + "mm_eunk": "Неопознанная ошибка", + "mm_e404": "Не удалось воспроизвести аудио; ошибка 404: Файл не найден.", + "mm_e403": "Не удалось воспроизвести аудио; ошибка 403: Доступ запрещён.\n\nПопробуйте перезагрузить страницу, возможно, ваша сессия истекла", + "mm_e500": "Не удалось воспроизвести аудио; ошибка 500: Проверьте логи сервера.", + "mm_e5xx": "Не удалось воспроизвести аудио; ошибка сервера ", + "mm_nof": "больше аудио-файлов не найдено", + "mm_prescan": "Поиск музыки для воспроизведения дальше...", + "mm_scank": "Найден следующий трек:", + "mm_uncache": "кеш очищен; все треки будут загружены заново при воспроизведении", + "mm_hnf": "это трек больше не существует", + + "im_hnf": "это изображение больше не существует", + + "f_empty": 'эта папка пуста', + "f_chide": 'это скроет столбец «{0}»\n\nвы можете показать скрытые столбцы в настройках', + "f_bigtxt": "объём данного файла - {0} МиБ. точно открыть как текст?", + "f_bigtxt2": "просмотреть только конец файла? это также включит обновление в реальном времени, показывая новые строки сразу после их добавления", + "fbd_more": '
показано {0} из {1} файлов; показать {2} или показать всё
', + "fbd_all": '
показано {0} из {1} файлов; показать всё
', + "f_anota": "только {0} из {1} файлов было выделено;\nчтобы выделить всё папку, отмотайте до низа", + + "f_dls": 'ссылки на файлы в данной папке были\nзаменены ссылками на скачивание', + + "f_partial": "Чтобы безопасно скачать файл, который в текущий момент загружается, нажмите на файл с таким же названием, но без расширения .PARTIAL. Пожалуйста, нажмите Отмена или ESC, чтобы сделать это.\n\nПри нажатии OK / Enter, вы скачаете этот временный файл, который с огромной вероятностью содержит лишь неполные данные.", + + "ft_paste": "вставить {0} файлов$NГорячая клавиша: ctrl-V", + "fr_eperm": 'не удалось переименовать:\nу вас нет разрешения “move” в этой папке', + "fd_eperm": 'не удалось удалить:\nу вас нет разрешения “delete” в этой папке', + "fc_eperm": 'не удалось вырезать:\nу вас нет разрешения “move” в этой папке', + "fp_eperm": 'не удалось вставить:\nу вас нет разрешения “write” в этой папке', + "fr_emore": "выделите хотя бы один файл, чтобы переименовать", + "fd_emore": "выделите хотя бы один файл, чтобы удалить", + "fc_emore": "выделите хотя бы один файл, чтобы вырезать", + "fcp_emore": "выделите хотя бы один файл, чтобы скопировать в буфер", + + "fs_sc": "поделиться текущей папкой", + "fs_ss": "поделиться выделенными файлами", + "fs_just1d": "вы не можете выбрать больше одной папки\nили смешивать файлы с папками при выделении", + "fs_abrt": "❌ отменить", + "fs_rand": "🎲 случ. имя", + "fs_go": "✅ создать доступ", + "fs_name": "имя", + "fs_src": "путь", + "fs_pwd": "пароль", + "fs_exp": "срок", + "fs_tmin": "мин", + "fs_thrs": "часов", + "fs_tdays": "дней", + "fs_never": "вечно", + "fs_pname": "имя ссылки; генерируется случайно если не указано", + "fs_tsrc": "путь к файлу или папке, которыми нужно поделиться", + "fs_ppwd": "пароль (необязательно)", + "fs_w8": "создаю доступ...", + "fs_ok": "нажмите Enter/OK, чтобы скопировать\nнажмите ESC/Cancel, чтобы закрыть", + + "frt_dec": "может исправить некоторые случаи с некорректными именами файлов\">декодировать url", + "frt_rst": "сбросить изменённые имена обратно к оригинальным\">↺ сброс", + "frt_abrt": "отменить операцию и закрыть это окно\">❌ отмена", + "frb_apply": "ПЕРЕИМЕНОВАТЬ", + "fr_adv": "переименование массовое / метаданных / по шаблону\">эксперт", + "fr_case": "чувствительный к регистру regex\">РеГиСтР", + "fr_win": "совместимые с windows имена; заменяет <>:"\\|?* японскими полноширинными символами\">win", + "fr_slash": "заменяет / символом, который не создаёт новые папки\">без /", + "fr_re": "поиск по шаблону regex, применяемый к оригинальным именам; группы захвата могут применяться в поле форматирования с помощью <code>(1)</code> и <code>(2)</code> и так далее", + "fr_fmt": "вдохновлено foobar2000:$N<code>(title)</code> заменяется названием трека,$N<code>[(artist) - ](title)</code> пропускает [эту] часть, если композитор не указан$N<code>$lpad((tn),2,0)</code> добавляет ведущие нули до двух цифр", + "fr_pdel": "удалить", + "fr_pnew": "сохранить как", + "fr_pname": "предоставьте название для нового шаблона", + "fr_aborted": "прервано", + "fr_lold": "старое имя", + "fr_lnew": "новое имя", + "fr_tags": "теги для выделенных файлов (не редактируется, это для инструкции):", + "fr_busy": "переименовываю {0} файлов...\n\n{1}", + "fr_efail": "ошибка переименования:\n", + "fr_nchg": "{0} новых имён были модифицированы для соответствия опциям win и/или без /\n\nХотите использовать эти имена?", + + "fd_ok": "успешно удалено", + "fd_err": "ошибка удаления:\n", + "fd_none": "ничего не удалено; возможно, не позволяет конфигурация сервера (xbd)?", + "fd_busy": "удалено {0} файлов...\n\n{1}", + "fd_warn1": "УДАЛИТЬ эти {0} файлов?", + "fd_warn2": "Внимание! Это необратимый процесс. Удалить?", + + "fc_ok": "вырезано {0} файлов", + "fc_warn": 'вырезано {0} файлов\n\nно только эта вкладка браузера может их вставить\n(поскольку выделение оказалось настолько огромным)', + + "fcc_ok": "скопировано {0} файлов в буфер", + "fcc_warn": 'скопировано {0} файлов в буфер\n\nно только эта вкладка браузера может их вставить\n(поскольку выделение оказалось настолько огромным)', + + "fp_apply": "использовать эти имена", + "fp_ecut": "сначала вырезать или скопировать только некоторые файлы / папки\n\nучтите: вы можете вырезать / вставлять файлы между вкладками", + "fp_ename": "{0} файлов невозможно перенести сюда, потому что их имена уже заняты. Введите имена ниже, чтобы продолжить, или оставьте поля пустыми, чтобы пропустить:", + "fcp_ename": "{0} файлов невозможно скопировать сюда, потому что их имена уже заняты. Введите имена ниже, чтобы продолжить, или оставьте поля пустыми, чтобы пропустить:", + "fp_emore": "есть ещё коллизии имён, которые требуется исправить", + "fp_ok": "успешно перенесено", + "fcp_ok": "успешно скопировано", + "fp_busy": "перемещаю {0} файлов...\n\n{1}", + "fcp_busy": "копирую {0} файлов...\n\n{1}", + "fp_err": "ошибка перемещения:\n", + "fcp_err": "ошибка копирования:\n", + "fp_confirm": "переместить эти {0} файлов сюда?", + "fcp_confirm": "скопировать эти {0} файлов сюда?", + "fp_etab": 'ошибка чтения буфера обмена из другой вкладки браузера', + "fp_name": "загружаю файл с вашего устройства. Назовите его:", + "fp_both_m": '
выберите, что вставить
Enter = Перенести {0} файлов из «{1}»\nESC = Загрузить {2} файлов с вашего устройства', + "fcp_both_m": '
выберите, что вставить
Enter = Скопировать {0} файлов из «{1}»\nESC = Загрузить {2} файлов с вашего устройства', + "fp_both_b": 'ПереместитьЗагрузить', + "fcp_both_b": 'СкопироватьЗагрузить', + + "mk_noname": "введите имя в текстовое поле слева перед тем, как это делать :p", + + "tv_load": "Загружаю текстовый документ:\n\n{0}\n\n{1}% ({2} из {3} МиБ загружено)", + "tv_xe1": "не удалось загрузить текстовый файл:\n\nошибка ", + "tv_xe2": "404, файл не найден", + "tv_lst": "список текстовых файлов в", + "tvt_close": "вернуться в обзор папки$NГорячая клавиша: M (или Esc)\">❌ закрыть", + "tvt_dl": "скачать этот файл$NГорячая клавиша: Y\">💾 скачать", + "tvt_prev": "показать предыдущий документ$NГорячая клавиша: i\">⬆ пред", + "tvt_next": "показать следующий документ$NГорячая клавиша: K\">⬇ след", + "tvt_sel": "выбрать документ   ( для вырезания / копирования / удаления / ... )$NГорячая клавиша: S\">выд", + "tvt_edit": "открыть документ в текстовом редакторе$NГорячая клавиша: E\">✏️ изменить", + "tvt_tail": "проверять файл на изменения; показывать новые строки в реальном времени\">📡 обновлять", + "tvt_wrap": "перенос слов\">↵", + "tvt_atail": "прикрепить вид к низу страницы\">⚓", + "tvt_ctail": "декодировать цвета терминала (ansi escape codes)\">🌈", + "tvt_ntail": "лимит прокрутки (как много байт текста держать в памяти)", + + "m3u_add1": "трек добавлен в плейлист m3u", + "m3u_addn": "{0} треков добавлено в плейлист m3u", + "m3u_clip": "плейлист m3u скопирован в буфер\n\nсоздайте файл с расширением .m3u и вставьте текст туда, чтобы сделать из него плейлист", + + "gt_vau": "не показывать видео, только воспроизводить аудио\">🎧", + "gt_msel": "включить режим выделения; держите ctrl при нажатии для инвертации действия$N$N<em>когда активно: дважды кликните на файле / папке, чтобы открыть их</em>$N$NГорячая клавиша: S\">выделение", + "gt_crop": "обрезать миниатюры\">обрезка", + "gt_3x": "миниатюры высокого разрешения\">3x", + "gt_zoom": "размер", + "gt_chop": "длина имён", + "gt_sort": "сортировать по", + "gt_name": "имени", + "gt_sz": "размеру", + "gt_ts": "дате", + "gt_ext": "типу", + "gt_c1": "укоротить названия файлов", + "gt_c2": "удлинить названия файлов", + + "sm_w8": "ищем...", + "sm_prev": "результаты поиска ниже - из предыдущего запроса:\n ", + "sl_close": "закрыть результаты поиска", + "sl_hits": "показ {0} совпадений", + "sl_moar": "загрузить больше", + + "s_sz": "размер", + "s_dt": "дата", + "s_rd": "путь", + "s_fn": "имя", + "s_ta": "теги", + "s_ua": "дата⬆️", + "s_ad": "другое", + "s_s1": "минимум МиБ", + "s_s2": "максимум МиБ", + "s_d1": "мин. iso8601", + "s_d2": "макс. iso8601", + "s_u1": "загружено после", + "s_u2": "и/или до", + "s_r1": "путь содержит   (разделить пробелами)", + "s_f1": "имя содержит   (для исключения писать -nope)", + "s_t1": "теги содержат   (^=начало, конец=$)", + "s_a1": "свойства метаданных", + + "md_eshow": "не удалось показать ", + "md_off": "[📜ридми] отключён в [⚙️] -- документ скрыт", + + "badreply": "Ошибка обработки ответа сервера", + + "xhr403": "403: Доступ запрещён\n\nпопробуйте перезагрузить страницу, возможно, ваша сессия истекла", + "xhr0": "неизвестно (возможно, потеряно соединение с сервером, либо он отключён)", + "cf_ok": "просим прощения -- сработала защита от DD" + wah + "oS\n\nвсё должно вернуться в норму через 30 сек\n\nесли ничего не происходит - перезагрузите страницу", + "tl_xe1": "не удалось показать подпапки:\n\nошибка ", + "tl_xe2": "404: Папка не найдена", + "fl_xe1": "не удалось показать файлы:\n\nошибка ", + "fl_xe2": "404: Папка не найдена", + "fd_xe1": "не удалось создать подпапку:\n\nошибка ", + "fd_xe2": "404: Родительская папка не найдена", + "fsm_xe1": "не удалось отправить сообщение:\n\nошибка ", + "fsm_xe2": "404: Родительская папка не найдена", + "fu_xe1": "не удалось удалить список с сервера:\n\nошибка ", + "fu_xe2": "404: Файл не найден??", + + "fz_tar": "несжатый файл gnu-tar (linux / mac)", + "fz_pax": "несжатый pax-форматированный tar (медленнее)", + "fz_targz": "gnu-tar с 3 уровнем сжатия gzip$N$Nобычно это очень медленно,$Nлучше использовать несжатый tar", + "fz_tarxz": "gnu-tar с 1 уровнем сжатия xz$N$Nобычно это очень медленно,$Nлучше использовать несжатый tar", + "fz_zip8": "zip с именами по utf8 (может работать криво на windows 7 и ниже)", + "fz_zipd": "zip с именами по cp437, для очень старого софта", + "fz_zipc": "cp437 с предварительным вычислением crc32,$N для MS-DOS PKZIP v2.04g (октябрь 1993)$N(требует больше времени для обработки перед скачиванием)", + + "un_m1": "вы можете удалить ваши недавние загрузки (или отменить незавершённые) ниже", + "un_upd": "обновить", + "un_m4": "или поделиться файлами снизу:", + "un_ulist": "показать", + "un_ucopy": "копировать", + "un_flt": "опциональный фильтр:  адрес должен содержать", + "un_fclr": "очистить фильтр", + "un_derr": 'ошибка удаления:\n', + "un_f5": 'что-то сломалось, пожалуйста перезагрузите страницу', + "un_uf5": "извините, но вам нужно перезагрузить страницу (F5 или Ctrl+R) перед тем, как отменить эту загрузку", + "un_nou": 'внимание: сервер слишком нагружен, чтобы показать незавершённые загрузки; нажмите на ссылку "обновления" через пару секунд', + "un_noc": 'внимание: удаление уже загруженных файлов запрещено конфигурацией сервера', + "un_max": "показаны первые 2000 файлов (используйте фильтр)", + "un_avail": "{0} недавних загрузок может быть удалено
{1} незавершённых может быть отменено", + "un_m2": "отсортировано по времени загрузки; сначала самые последние:", + "un_no1": "ха, поверил! достаточно свежих загрузок ещё нет", + "un_no2": "ха, поверил! достаточно свежих загрузок, соответствующих фильтру, ещё нет", + "un_next": "удалить следующие {0} файлов ниже", + "un_abrt": "отменить", + "un_del": "удалить", + "un_m3": "загружаю ваши недавние загрузки...", + "un_busy": "удаляю {0} файлов...", + "un_clip": "{0} ссылок скопировано в буфер", + + "u_https1": "вам стоит", + "u_https2": "включить https", + "u_https3": "для лучшей производительности", + "u_ancient": 'у вас действительно антикварный браузер -- возможно, стоит использовать bup', + "u_nowork": "требуется firefox 53+, chrome 57+ или iOS 11+", + "tail_2old": "требуется firefox 105+, chrome 71+ или iOS 14.5+", + "u_nodrop": 'ваш браузер слишком старый для загрузки через перетаскивание', + "u_notdir": "это не папка!\n\nваш браузер слишком старый,\nиспользуйте перетаскивание", + "u_uri": "чтобы перетащить картинку из других окон браузера,\nотпустите её на большую кнопку загрузки", + "u_enpot": 'переключиться на простой интерфейс (может ускорить загрузку)', + "u_depot": 'переключиться на модный интерфейс (может замедлить загрузку)', + "u_gotpot": 'переключаюсь на простой интерфес для ускорения загрузки,\n\nможете переключиться обратно, если хотите!', + "u_pott": "

файлы:   {0} завершено,   {1} ошибок,   {2} загружаются,   {3} в очереди

", + "u_ever": "это упрощённый загрузчик; up2k требует хотя бы
chrome 21 // firefox 13 // edge 12 // opera 12 // safari 5.1", + "u_su2k": 'это упрощённый загрузчик; up2k лучше', + "u_uput": 'увеличить скорость (пропуск подсчёта контрольных сумм)', + "u_ewrite": 'у вас нет прав на запись в эту папку', + "u_eread": 'у вас нет прав на чтение из этой папки', + "u_enoi": 'поиск файлов выключен настройками сервера', + "u_enoow": "перезапись здесь не работает; требуются права на удаление", + "u_badf": 'Эти {0} из {1} файлов были пропущены, вероятно, из-за настроек доступа в файловой системе:\n\n', + "u_blankf": 'Эти {0} из {1} файлов пустые; всё равно загрузить?\n\n', + "u_applef": 'Эти {0} из {1} файлов, вероятно, нежелательны;\nНажмите OK/Enter, чтобы ПРОПУСТИТЬ их,\nНажмите Отмена/ESC, чтобы проигнорировать сообщение и ЗАГРУЗИТЬ их:\n\n', + "u_just1": '\nВозможно, будет лучше, если вы выберете только один файл', + "u_ff_many": "если вы используете Linux / MacOS / Android, тогда такое количество файлов может крашнуть Firefox!\nв таком случае попробуйте снова (или используйте Chrome).", + "u_up_life": "Эта загрузка будет удалена с сервера\nчерез {0} после её завершения", + "u_asku": 'загрузить эти {0} файлов в {1}', + "u_unpt": "вы можете отменить / удалить эту загрузку с помощью 🧯 сверху слева", + "u_bigtab": 'будет показано {0} файлов\n\nэто может крашнуть браузер, вы уверены?', + "u_scan": 'Сканирую файлы...', + "u_dirstuck": 'сканер папки завис при попытке получить доступ к следующим {0} файлам; будет пропущено:', + "u_etadone": 'Готово ({0}, {1} файлов)', + "u_etaprep": '(подготавливаю загрузку)', + "u_hashdone": 'хеширование выполнено', + "u_hashing": 'хеш', + "u_hs": 'подготовка к хешированию...', + "u_started": "файлы загружаются; подробнее в [🚀]", + "u_dupdefer": "дубликат; будет обработан после всех остальных файлов", + "u_actx": "нажмите на этот текст, чтобы предотвратить
падение производительности при просмотре других вкладок / окон", + "u_fixed": "Окей!  Исправлено 👍", + "u_cuerr": "не удалось загрузить фрагмент {0} из {1};\nвероятно, не критично - продолжаю\n\nфайл: {2}", + "u_cuerr2": "отказ в загрузке (фрагмент {0} из {1});\nпопытаюсь повторить позже\n\nфайл: {2}\n\nошибка ", + "u_ehstmp": "попытаюсь повторить позже; подробнее снизу справа", + "u_ehsfin": "отказ в запросе завершения загрузки; повторяю...", + "u_ehssrch": "отказ в запросе поиска; повторяю...", + "u_ehsinit": "отказ в запросе начала загрузки; повторяю...", + "u_eneths": "ошибка подключения во время подготовки загрузки; повторяю...", + "u_enethd": "ошибка подключения во время проверки существования целевого файла; повторяю...", + "u_cbusy": "ожидаю возвращения доступа к серверу после ошибки подключения...", + "u_ehsdf": "на сервере закончилось место!\n\nбуду пытаться повторить, на случай если\nместо будет освобождено", + "u_emtleak1": "кажется, у вашего браузера может быть утечка памяти;\nпожалуйста,", + "u_emtleak2": ' перейдите на https (рекомендовано) или ', + "u_emtleak3": ' ', + "u_emtleakc": 'попробуйте сделать так:\nОна будет чуть медленнее, но что поделать.\nИзвините за неудобства!\n\nPS: в chrome v107 это исправили', + "u_emtleakf": 'попробуйте сделать так:\n\nPS: firefox скоро должны починить в этом аспекте', + "u_s404": "не найдено на сервере", + "u_expl": "объяснить", + "u_maxconn": "в большинстве браузеров это нельзя поднять выше 6, но firefox позволяет увеличить лимит с помощью connections-per-server в about:config", + "u_tu": '

ВНИМАНИЕ: активен режим турбо,  клиент может игнорировать незавершённые загрузки; подробнее при наведении на кнопку турбо

', + "u_ts": '

ВНИМАНИЕ: активен режим турбо,  результаты поиска могут быть некорректными; подробнее при наведении на кнопку турбо

', + "u_turbo_c": "режим турбо отключён сервером", + "u_turbo_g": "отключаю турбо, поскольку у вас нет прав\nна просмотр папок в этом хранилище", + "u_life_cfg": 'автоудаление через мин (или часов)', + "u_life_est": 'загрузка будет удалена ---', + "u_life_max": 'эта папка требует\nавтоудаления файлов через {0}', + "u_unp_ok": 'удаление разрешено для {0}', + "u_unp_ng": 'удаление НЕ будет разрешено', + "ue_ro": 'ваш доступ к данной папке - только чтение\n\n', + "ue_nl": 'на данный момент вы не авторизованы', + "ue_la": 'вы авторизованы как "{0}"', + "ue_sr": 'сейчас вы в режиме поиска файлов\n\nперейдите в режим загрузки, нажав на лупу 🔎 (рядом с огромной кнопкой ИСКАТЬ), и попробуйте снова\n\nизвините', + "ue_ta": 'попробуйте загрузить снова, теперь должно сработать', + "ue_ab": "этот файл уже загружают в другую папку, та загрузка должна быть завершена перед тем, как загрузить этот же файл в другое место.\n\nВы можете отменить свою загрузку через 🧯 сверху слева", + "ur_1uo": "OK: Файл успешно загружен", + "ur_auo": "OK: Все {0} файлов успешно загружены", + "ur_1so": "OK: Файл найден на сервере", + "ur_aso": "OK: Все {0} файлов найдены на сервере", + "ur_1un": "Загрузка не удалась, извините", + "ur_aun": "Все {0} загрузок не удались, извините", + "ur_1sn": "Файл НЕ был найден на сервере", + "ur_asn": "Все {0} файлов НЕ было найдено на сервере", + "ur_um": "Завершено;\n{0} успешно,\n{1} ошибок, извините", + "ur_sm": "Завершено;\n{0} файлов найдено на сервере,\n{1} файлов НЕ найдено на сервере", + + "lang_set": "перезагрузить страницу, чтобы применить изменения?", + }, + "spa": { + "tt": "Español", + + "cols": { + "c": "acciones", + "dur": "duración", + "q": "calidad / bitrate", + "Ac": "códec de audio", + "Vc": "códec de vídeo", + "Fmt": "formato / contenedor", + "Ahash": "checksum de audio", + "Vhash": "checksum de vídeo", + "Res": "resolución", + "T": "tipo de archivo", + "aq": "calidad de audio / bitrate", + "vq": "calidad de vídeo / bitrate", + "pixfmt": "submuestreo / estructura de píxel", + "resw": "resolución horizontal", + "resh": "resolución vertical", + "chs": "canales de audio", + "hz": "frecuencia de muestreo" + }, + + "hks": [ + [ + "varios", + ["ESC", "cerrar varias cosas"], + + "gestor de archivos", + ["G", "alternar vista de lista / cuadrícula"], + ["T", "alternar miniaturas / iconos"], + ["⇧ A/D", "tamaño de miniatura"], + ["ctrl-K", "eliminar seleccionados"], + ["ctrl-X", "cortar selección al portapapeles"], + ["ctrl-C", "copiar selección al portapapeles"], + ["ctrl-V", "pegar (mover/copiar) aquí"], + ["Y", "descargar seleccionados"], + ["F2", "renombrar seleccionados"], + + "selección en lista de archivos", + ["space", "alternar selección de archivo"], + ["↑/↓", "mover cursor de selección"], + ["ctrl ↑/↓", "mover cursor y vista"], + ["⇧ ↑/↓", "seleccionar anterior/siguiente archivo"], + ["ctrl-A", "seleccionar todos los archivos / carpetas"] + ], [ + "navegación", + ["B", "alternar breadcrumbs / panel de navegación"], + ["I/K", "anterior/siguiente carpeta"], + ["M", "carpeta de nivel superior (o contraer actual)"], + ["V", "alternar carpetas / archivos en panel de navegación"], + ["A/D", "tamaño del panel de navegación"] + ], [ + "reproductor de audio", + ["J/L", "anterior/siguiente canción"], + ["U/O", "saltar 10s atrás/adelante"], + ["0..9", "saltar a 0%..90%"], + ["P", "reproducir/pausar (también inicia)"], + ["S", "seleccionar canción en reproducción"], + ["Y", "descargar canción"] + ], [ + "visor de imágenes", + ["J/L, ←/→", "anterior/siguiente imagen"], + ["Home/End", "primera/última imagen"], + ["F", "pantalla completa"], + ["R", "rotar en sentido horario"], + ["⇧ R", "rotar en sentido antihorario"], + ["S", "seleccionar imagen"], + ["Y", "descargar imagen"] + ], [ + "reproductor de vídeo", + ["U/O", "saltar 10s atrás/adelante"], + ["P/K/Space", "reproducir/pausar"], + ["C", "continuar con el siguiente"], + ["V", "bucle"], + ["M", "silenciar"], + ["[ y ]", "establecer intervalo de bucle"] + ], [ + "visor de texto", + ["I/K", "anterior/siguiente archivo"], + ["M", "cerrar archivo"], + ["E", "editar archivo"], + ["S", "seleccionar archivo (para cortar/copiar/renombrar)"] + ] + ], + + "m_ok": "Aceptar", + "m_ng": "Cancelar", + + "enable": "Activar", + "danger": "PELIGRO", + "clipped": "copiado al portapapeles", + + "ht_s1": "segundo", + "ht_s2": "segundos", + "ht_m1": "minuto", + "ht_m2": "minutos", + "ht_h1": "hora", + "ht_h2": "horas", + "ht_d1": "día", + "ht_d2": "días", + "ht_and": " y ", + + "goh": "panel de control", + "gop": 'hermano anterior">anterior', + "gou": 'carpeta de nivel superior">subir', + "gon": 'siguiente carpeta">siguiente', + "logout": "Cerrar sesión ", + "access": " acceso", + "ot_close": "cerrar submenú", + "ot_search": "buscar archivos por atributos, ruta / nombre, etiquetas de música, o cualquier combinación$N$N<code>foo bar</code> = debe contener «foo» y «bar»,$N<code>foo -bar</code> = debe contener «foo» pero no «bar»,$N<code>^yana .opus$</code> = empieza con «yana» y es un archivo «opus»$N<code>"try unite"</code> = contiene exactamente «try unite»$N$Nel formato de fecha es iso-8601, como$N<code>2009-12-31</code> o <code>2020-09-12 23:30:00</code>", + "ot_unpost": "dessubir: elimina tus subidas recientes, o aborta las inacabadas", + "ot_bup": "bup: uploader básico, soporta hasta netscape 4.0", + "ot_mkdir": "mkdir: crear un nuevo directorio", + "ot_md": "new-md: crear un nuevo documento markdown", + "ot_msg": "msg: enviar un mensaje al registro del servidor", + "ot_mp": "opciones del reproductor multimedia", + "ot_cfg": "opciones de configuración", + "ot_u2i": "up2k: subir archivos (si tienes acceso de escritura) o cambiar a modo de búsqueda para ver si existen en el servidor$N$Nlas subidas se pueden reanudar, usan múltiples hilos y conservan la fecha de los archivos, pero consume más CPU que [🎈]  (el uploader básico)

¡Durante las subidas, este icono se convierte en un indicador de progreso!", + "ot_u2w": "up2k: subir archivos con soporte para reanudación (cierra tu navegador y arrastra los mismos archivos más tarde)$N$NMultihilo y conserva las fechas de los archivos, pero usa más CPU que [🎈]  (el uploader básico)

¡Durante las subidas, este icono se convierte en un indicador de progreso!", + "ot_noie": "Por favor, usa Chrome / Firefox / Edge", + + "ab_mkdir": "crear directorio", + "ab_mkdoc": "nuevo documento markdown", + "ab_msg": "enviar msg al registro del servidor", + + "ay_path": "saltar a carpetas", + "ay_files": "saltar a archivos", + + "wt_ren": "renombrar elementos seleccionados$NAtajo: F2", + "wt_del": "eliminar elementos seleccionados$NAtajo: ctrl-K", + "wt_cut": "cortar elementos seleccionados <small>(luego pegar en otro lugar)</small>$NAtajo: ctrl-X", + "wt_cpy": "copiar elementos seleccionados al portapapeles$N(para pegarlos en otro lugar)$NAtajo: ctrl-C", + "wt_pst": "pegar una selección previamente cortada / copiada$NAtajo: ctrl-V", + "wt_selall": "seleccionar todos los archivos$NAtajo: ctrl-A (con un archivo con foco)", + "wt_selinv": "invertir selección", + "wt_zip1": "descargar esta carpeta como un archivo comprimido", + "wt_selzip": "descargar selección como archivo comprimido", + "wt_seldl": "descargar selección como archivos separados$NAtajo: Y", + "wt_npirc": "copiar información de pista en formato IRC", + "wt_nptxt": "copiar información de pista en texto plano", + "wt_m3ua": "añadir a lista m3u (haz clic en 📻copiar después)", + "wt_m3uc": "copiar lista m3u al portapapeles", + "wt_grid": "alternar vista de cuadrícula / lista$NAtajo: G", + "wt_prev": "pista anterior$NAtajo: J", + "wt_play": "reproducir / pausar$NAtajo: P", + "wt_next": "siguiente pista$NAtajo: L", + + "ul_par": "subidas paralelas:", + "ut_rand": "aleatorizar nombres de archivo", + "ut_u2ts": 'copiar la fecha de última modificación$Nde tu sistema de archivos al servidor">📅', + "ut_ow": "sobrescribir archivos existentes en el servidor?$N🛡️: nunca (generará un nuevo nombre de archivo en su lugar)$N🕒: sobrescribir si el archivo del servidor es más antiguo que el tuyo$N♻️: siempre sobrescribir si los archivos son diferentes", + "ut_mt": "continuar generando hashes de otros archivos mientras se sube$N$Nquizás desactivar si tu CPU o HDD es un cuello de botella", + "ut_ask": 'pedir confirmación antes de iniciar la subida">💭', + "ut_pot": "mejorar la velocidad de subida en dispositivos lentos$Nsimplificando la interfaz de usuario", + "ut_srch": "no subir, en su lugar comprobar si los archivos ya $N existen en el servidor (escaneará todas las carpetas que puedas leer)", + "ut_par": "pausar subidas poniéndolo a 0$N$Naumentar si tu conexión es lenta / de alta latencia$N$Nmantener en 1 en LAN o si el HDD del servidor es un cuello de botella", + "ul_btn": "arrastra archivos / carpetas
aquí (o haz clic)", + "ul_btnu": "S U B I R", + "ul_btns": "B U S C A R", + + "ul_hash": "hash", + "ul_send": "envio", + "ul_done": "hecho", + "ul_idle1": "aún no hay subidas en cola", + "ut_etah": "velocidad media de <em>hashing</em>, y tiempo estimado para finalizar", + "ut_etau": "velocidad media de <em>subida</em> y tiempo estimado para finalizar", + "ut_etat": "velocidad media <em>total</em> y tiempo estimado para finalizar", + + "uct_ok": "completado con éxito", + "uct_ng": "fallido: error / rechazado / no encontrado", + "uct_done": "éxitos y fallos combinados", + "uct_bz": "generando hash o subiendo", + "uct_q": "inactivo, pendiente", + + "utl_name": "nombre de archivo", + "utl_ulist": "lista", + "utl_ucopy": "copiar", + "utl_links": "enlaces", + "utl_stat": "estado", + "utl_prog": "progreso", + + "utl_404": "404", + "utl_err": "ERROR", + "utl_oserr": "Error-SO", + "utl_found": "encontrado", + "utl_defer": "posponer", + "utl_yolo": "YOLO", + "utl_done": "hecho", + + "ul_flagblk": "los archivos se añadieron a la cola
sin embargo, hay un up2k ocupado en otra pestaña del navegador,
esperando a que termine primero", + "ul_btnlk": "la configuración del servidor ha bloqueado esta opción en este estado", + + "udt_up": "Subir", + "udt_srch": "Buscar", + "udt_drop": "suéltalo aquí", + + "u_nav_m": "
vale, ¿qué tienes?
Intro = Archivos (uno o más)\nESC = Una carpeta (incluyendo subcarpetas)", + "u_nav_b": "ArchivosUna carpeta", + + "cl_opts": "opciones", + "cl_themes": "tema", + "cl_langs": "idioma", + "cl_ziptype": "descarga de carpeta", + "cl_uopts": "opciones up2k", + "cl_favico": "favicon", + "cl_bigdir": "directorios grandes", + "cl_hsort": "#ordenar", + "cl_keytype": "notación musical", + "cl_hiddenc": "columnas ocultas", + "cl_hidec": "ocultar", + "cl_reset": "restablecer", + "cl_hpick": "toca en las cabeceras de columna para ocultarlas en la tabla de abajo", + "cl_hcancel": "ocultación de columna cancelada", + + "ct_grid": '田 cuadrícula', + "ct_ttips": '◔ ◡ ◔">ℹ️ tooltips', + "ct_thumb": 'en vista de cuadrícula, alternar iconos o miniaturas$NAtajo: T">🖼️ miniaturas', + "ct_csel": 'usa CTRL y SHIFT para seleccionar archivos en la vista de cuadrícula">sel', + "ct_ihop": 'al cerrar el visor de imágenes, desplazarse hasta el último archivo visto">g⮯', + "ct_dots": 'mostrar archivos ocultos (si el servidor lo permite)">archivos ocultos', + "ct_qdel": 'al eliminar archivos, pedir confirmación solo una vez">elim. rápida', + "ct_dir1st": 'ordenar carpetas antes que archivos">📁 primero', + "ct_nsort": 'orden natural (para nombres de archivo con dígitos iniciales)">ord. natural', + "ct_utc": 'use UTC para todas las horas">UTC', //m + "ct_readme": 'mostrar README.md en los listados de carpetas">📜 léeme', + "ct_idxh": 'mostrar index.html en lugar del listado de carpetas">htm', + "ct_sbars": 'mostrar barra lateral">⟊', + + "cut_umod": 'si un archivo ya existe en el servidor, actualiza la fecha de última modificación del servidor para que coincida con tu archivo local (requiere permisos de escritura+eliminación)">re📅', + + "cut_turbo": 'el botón yolo, probablemente NO quieras activarlo:$N$Núsalo si estabas subiendo una gran cantidad de archivos y tuviste que reiniciar por alguna razón, y quieres continuar la subida lo antes posible$N$Nesto reemplaza la comprobación de hash por un simple "¿tiene este el mismo tamaño de archivo en el servidor?" así que si el contenido del archivo es diferente, NO se subirá$N$Ndeberías desactivar esto cuando la subida termine, y luego "subir" los mismos archivos de nuevo para que el cliente los verifique">turbo', + + "cut_datechk": 'no tiene efecto a menos que el botón turbo esté activado$N$Nreduce el factor yolo en una pequeña cantidad; comprueba si las fechas de los archivos en el servidor coinciden con las tuyas$N$Nteóricamente debería detectar la mayoría de las subidas inacabadas / corruptas, pero no es un sustituto de hacer una pasada de verificación con el turbo desactivado después">verif. fecha', + + "cut_u2sz": "tamaño (en MiB) de cada trozo de subida; los valores grandes vuelan mejor a través del atlántico. Prueba valores bajos en conexiones muy poco fiables", + + "cut_flag": "asegura que solo una pestaña esté subiendo a la vez $N -- otras pestañas también deben tener esto activado $N -- solo afecta a pestañas en el mismo dominio", + + "cut_az": "subir archivos en orden alfabético, en lugar de los más pequeños primero$N$Nel orden alfabético puede facilitar la detección visual de si algo salió mal en el servidor, pero hace la subida ligeramente más lenta en fibra / LAN", + + "cut_nag": "notificación del SO cuando la subida se complete$N(solo si el navegador o la pestaña no están activos)", + "cut_sfx": "alerta sonora cuando la subida se complete$N(solo si el navegador o la pestaña no están activos)", + + "cut_mt": 'usar multithreading para acelerar el hashing de archivos$N$Nesto usa web-workers y requiere$Nmás RAM (hasta 512 MiB extra)$N$Nhace https un 30% más rápido, http 4.5x más rápido">mt', + + "cut_wasm": 'usar wasm en lugar del hasher incorporado del navegador; mejora la velocidad en navegadores basados en chrome pero aumenta la carga de la CPU, y muchas versiones antiguas de chrome tienen errores que hacen que el navegador consuma toda la RAM y se bloquee si esto está activado">wasm', + + "cft_text": "texto del favicon (dejar en blanco y refrescar para desactivar)", + "cft_fg": "color de primer plano", + "cft_bg": "color de fondo", + + "cdt_lim": "número máximo de archivos a mostrar en una carpeta", + "cdt_ask": "al llegar al final,$Nen lugar de cargar más archivos,$Npreguntar qué hacer", + "cdt_hsort": "cuántas reglas de ordenación (<code>,sorthref</code>) incluir en las URLs de medios. Ponerlo a 0 también ignorará las reglas de ordenación incluidas en los enlaces de medios al hacer clic en ellos", + + "tt_entree": "mostrar panel de navegación (barra lateral con árbol de directorios)$NAtajo: B", + "tt_detree": "mostrar breadcrumbs$NAtajo: B", + "tt_visdir": "desplazarse a la carpeta seleccionada", + "tt_ftree": "alternar árbol de carpetas / archivos de texto$NAtajo: V", + "tt_pdock": "mostrar carpetas de niveles superiores en un panel acoplado en la parte superior", + "tt_dynt": "crecimiento automático a medida que el árbol se expande", + "tt_wrap": "ajuste de línea", + "tt_hover": "revelar líneas que se desbordan al pasar el ratón$N( rompe el desplazamiento a menos que el $N  cursor esté en el margen izquierdo )", + + "ml_pmode": "al final de la carpeta...", + "ml_btns": "acciones", + "ml_tcode": "transcodificar", + "ml_tcode2": "transcodificar a", + "ml_tint": "tinte", + "ml_eq": "ecualizador de audio", + "ml_drc": "compresor de rango dinámico", + + "mt_loop": 'poner en bucle/repetir una canción">🔁', + "mt_one": 'parar después de una canción">1️⃣', + "mt_shuf": 'reproducir aleatoriamente las canciones en cada carpeta">🔀', + "mt_aplay": 'reproducir automaticamente si hay un ID de canción en el enlace en el que hiciste clic para acceder al servidor$N$Ndesactivar esto también evitará que la URL de la página se actualice con IDs de canción al reproducir música, para prevenir la reproducción automática si se pierden estos ajustes pero la URL permanece">a▶', + "mt_preload": 'empezar a cargar la siguiente canción cerca del final para una reproducción sin pausas">precarga', + "mt_prescan": 'ir a la siguiente carpeta antes de que la última canción$Ntermine, manteniendo contento al navegador$Npara que no detenga la reproducción">nav', + "mt_fullpre": 'intentar precargar la canción entera;$N✅ activar en conexiones inestables,$N❌ desactivar probablemente en conexiones lentas">completa', + "mt_fau": 'en teléfonos, evitar que la música se detenga si la siguiente canción no se precarga lo suficientemente rápido (puede causar fallos en la visualización de etiquetas)">☕️', + "mt_waves": 'barra de búsqueda con forma de onda:$Nmostrar la amplitud del audio en la barra de progreso">~s', + "mt_npclip": 'mostrar botones para copiar al portapapeles la canción actual">/np', + "mt_m3u_c": 'mostrar botones para copiar al portapapeles las$Ncanciones seleccionadas como entradas de lista m3u8">📻', + "mt_octl": 'integración con SO (teclas multimedia / OSD)">ctl-so', + "mt_oseek": 'permitir buscar a través de la integración con el SO$N$Nnota: en algunos dispositivos (iPhones),$Nesto reemplaza el botón de siguiente canción">búsqueda', + "mt_oscv": 'mostrar carátula del álbum en OSD">arte', + "mt_follow": 'mantener la pista en reproducción visible en pantalla">🎯', + "mt_compact": 'controles compactos">⟎', + "mt_uncache": 'limpiar caché  (prueba esto si tu navegador guardó en caché$Nuna copia rota de una canción que se niega a reproducir)">limpiar caché', + "mt_mloop": 'repetir la carpeta actual">🔁 bucle', + "mt_mnext": 'cargar la siguiente carpeta y continuar">📂 sig', + "mt_mstop": 'detener reproducción">⏸ parar', + "mt_cflac": 'convertir flac / wav a opus">flac', + "mt_caac": 'convertir aac / m4a a opus">aac', + "mt_coth": 'convertir todos los demás (no mp3) a opus">oth', + "mt_c2opus": 'la mejor opción para ordenadores, portátiles, android">opus', + "mt_c2owa": 'opus-weba, para iOS 17.5 y superior">owa', + "mt_c2caf": 'opus-caf, para iOS 11 a 17">caf', + "mt_c2mp3": 'usar en dispositivos muy antiguos">mp3', + "mt_c2ok": "bien, buena elección", + "mt_c2nd": "ese no es el formato de salida recomendado para tu dispositivo, pero está bien", + "mt_c2ng": "tu dispositivo no parece soportar este formato de salida, pero intentémoslo de todas formas", + "mt_xowa": "hay errores en iOS que impiden la reproducción en segundo plano con este formato; por favor, usa caf o mp3 en su lugar", + "mt_tint": "nivel de fondo (0-100) en la barra de búsqueda$Npara hacer el buffering menos molesto", + "mt_eq": "activa el ecualizador y el control de ganancia;$N$Nganancia <code>0</code> = volumen estándar 100% (sin modificar)$N$Nancho <code>1  </code> = estéreo estándar (sin modificar)$Nancho <code>0.5</code> = 50% de crossfeed izq-der$Nancho <code>0  </code> = mono$N$Nganancia <code>-0.8</code> y ancho <code>10</code> = eliminación de voz :^)$N$Nactivar el ecualizador hace que los álbumes sin pausas sean completamente sin pausas, así que déjalo activado con todos los valores a cero (excepto ancho = 1) si eso te importa", + "mt_drc": "activa el compresor de rango dinámico (aplanador de volumen / brickwaller); también activará el EQ para equilibrar el espagueti, así que pon todos los campos de EQ excepto 'ancho' a 0 si no lo quieres$N$Nbaja el volumen del audio por encima de THRESHOLD dB; por cada RATIO dB pasado THRESHOLD hay 1 dB de salida, así que los valores por defecto de umbral -24 y ratio 12 significan que nunca debería sonar más fuerte de -22 dB y es seguro aumentar la ganancia del ecualizador a 0.8, o incluso 1.8 con ATK 0 y un RLS enorme como 90 (solo funciona en firefox; RLS es máx. 1 en otros navegadores)$N$N(ver wikipedia, lo explican mucho mejor)", + + "mb_play": "reproducir", + "mm_hashplay": "¿reproducir este archivo de audio?", + "mm_m3u": "pulsa Intro/Aceptar para Reproducir\npulsa ESC/Cancelar para Editar", + "mp_breq": "se necesita firefox 82+ o chrome 73+ o iOS 15+", + "mm_bload": "cargando...", + "mm_bconv": "convirtiendo a {0}, por favor espera...", + "mm_opusen": "tu navegador no puede reproducir archivos aac / m4a;\nse ha activado la transcodificación a opus", + "mm_playerr": "fallo de reproducción: ", + "mm_eabrt": "El intento de reproducción fue cancelado", + "mm_enet": "Tu conexión a internet es inestable", + "mm_edec": "¿Este archivo está supuestamente corrupto?", + "mm_esupp": "Tu navegador no entiende este formato de audio", + "mm_eunk": "Error desconocido", + "mm_e404": "No se pudo reproducir el audio; error 404: Archivo no encontrado.", + "mm_e403": "No se pudo reproducir el audio; error 403: Acceso denegado.\n\nIntenta pulsar F5 para recargar, quizás se cerró tu sesión", + "mm_e500": "No se pudo reproducir el audio; error 500: Revisa los registros del servidor.", + "mm_e5xx": "No se pudo reproducir el audio; error del servidor ", + "mm_nof": "no se encuentran más archivos de audio cerca", + "mm_prescan": "Buscando música para reproducir a continuación...", + "mm_scank": "Encontrada la siguiente canción:", + "mm_uncache": "caché limpiada; todas las canciones se volverán a descargar en la próxima reproducción", + "mm_hnf": "esa canción ya no existe", + + "im_hnf": "esa imagen ya no existe", + + "f_empty": "esta carpeta está vacía", + "f_chide": "esto ocultará la columna «{0}»\n\npuedes volver a mostrar las columnas en la pestaña de configuración", + "f_bigtxt": "este archivo pesa {0} MiB -- ¿realmente verlo como texto?", + "f_bigtxt2": "¿ver solo el final del archivo en su lugar? esto también activará el seguimiento, mostrando las líneas de texto recién añadidas en tiempo real", + "fbd_more": '
mostrando {0} de {1} archivos; mostrar {2} o mostrar todos
', + "fbd_all": '
mostrando {0} de {1} archivos; mostrar todos
', + "f_anota": "solo {0} de los {1} elementos fueron seleccionados;\npara seleccionar la carpeta completa, primero desplázate hasta el final", + + "f_dls": "los enlaces a archivos en la carpeta actual se han\nconvertido en enlaces de descarga", + + "f_partial": "Para descargar de forma segura un archivo que se está subiendo actualmente, por favor haz clic en el archivo con el mismo nombre, pero sin la extensión .PARTIAL. Por favor, pulsa CANCELAR o Escape para hacer esto.\n\nPulsar ACEPTAR o Intro ignorará esta advertencia y continuará descargando el archivo temporal .PARTIAL, lo que casi con toda seguridad te dará datos corruptos.", + + "ft_paste": "pegar {0} elementos$NAtajo: ctrl-V", + "fr_eperm": "no se puede renombrar:\nno tienes permiso de “mover” en esta carpeta", + "fd_eperm": "no se puede eliminar:\nno tienes permiso de “eliminar” en esta carpeta", + "fc_eperm": "no se puede cortar:\nno tienes permiso de “mover” en esta carpeta", + "fp_eperm": "no se puede pegar:\nno tienes permiso de “escribir” en esta carpeta", + "fr_emore": "selecciona al menos un elemento para renombrar", + "fd_emore": "selecciona al menos un elemento para eliminar", + "fc_emore": "selecciona al menos un elemento para cortar", + "fcp_emore": "selecciona al menos un elemento para copiar al portapapeles", + + "fs_sc": "compartir la carpeta en la que estás", + "fs_ss": "compartir los archivos seleccionados", + "fs_just1d": "no puedes seleccionar más de una carpeta,\no mezclar archivos y carpetas en una selección", + "fs_abrt": "❌ abortar", + "fs_rand": "🎲 nombre aleatorio", + "fs_go": "✅ crear enlace", + "fs_name": "nombre", + "fs_src": "origen", + "fs_pwd": "contraseña", + "fs_exp": "caducidad", + "fs_tmin": "minutos", + "fs_thrs": "horas", + "fs_tdays": "días", + "fs_never": "eterno", + "fs_pname": "nombre opcional del enlace; será aleatorio si se deja en blanco", + "fs_tsrc": "el archivo o carpeta a compartir", + "fs_ppwd": "contraseña opcional", + "fs_w8": "creando enlace...", + "fs_ok": "pulsa Intro/Aceptar para Copiar al Portapapeles\npulsa ESC/Cancelar para Cerrar", + + "frt_dec": "puede arreglar algunos casos de nombres de archivo rotos\">url-decode", + "frt_rst": "restaurar los nombres de archivo modificados a los originales\">↺ restablecer", + "frt_abrt": "abortar y cerrar esta ventana\">❌ cancelar", + "frb_apply": "APLICAR RENOMBRADO", + "fr_adv": "renombrado por lotes / metadatos / patrones\">avanzado", + "fr_case": "regex sensible a mayúsculas\">mayús", + "fr_win": "nombres seguros para windows; reemplaza <>:"\\|?* con caracteres japoneses de ancho completo\">win", + "fr_slash": "reemplaza / con un carácter que no cree nuevas carpetas\">sin /", + "fr_re": "patrón de búsqueda regex para aplicar a los nombres de archivo originales; los grupos de captura se pueden referenciar en el campo de formato de abajo como <code>(1)</code> y <code>(2)</code> y así sucesivamente", + "fr_fmt": "inspirado en foobar2000:$N<code>(title)</code> se reemplaza por el título de la canción,$N<code>[(artist) - ](title)</code> omite la parte [entre corchetes] si el artista está en blanco$N<code>$lpad((tn),2,0)</code> rellena el número de pista a 2 dígitos", + "fr_pdel": "eliminar", + "fr_pnew": "guardar como", + "fr_pname": "proporciona un nombre para tu nuevo preajuste", + "fr_aborted": "abortado", + "fr_lold": "nombre antiguo", + "fr_lnew": "nombre nuevo", + "fr_tags": "etiquetas para los archivos seleccionados (solo lectura, como referencia):", + "fr_busy": "renombrando {0} elementos...\n\n{1}", + "fr_efail": "fallo al renombrar:\n", + "fr_nchg": "{0} de los nuevos nombres fueron alterados debido a win y/o sin /\n\n¿Aceptar para continuar con estos nuevos nombres alterados?", + + "fd_ok": "eliminación correcta", + "fd_err": "fallo al eliminar:\n", + "fd_none": "no se eliminó nada; quizás bloqueado por la configuración del servidor (xbd)?", + "fd_busy": "eliminando {0} elementos...\n\n{1}", + "fd_warn1": "¿ELIMINAR estos {0} elementos?", + "fd_warn2": "¡Última oportunidad! No se puede deshacer. ¿Eliminar?", + + "fc_ok": "cortados {0} elementos", + "fc_warn": "cortados {0} elementos\n\npero: solo esta pestaña del navegador puede pegarlos\n(dado que la selección es absolutamente masiva)", + + "fcc_ok": "copiados {0} elementos al portapapeles", + "fcc_warn": "copiados {0} elementos al portapapeles\n\npero: solo esta pestaña del navegador puede pegarlos\n(dado que la selección es absolutamente masiva)", + + "fp_apply": "usar estos nombres", + "fp_ecut": "primero corta o copia algunos archivos / carpetas para pegar / mover\n\nnota: puedes cortar / pegar entre diferentes pestañas del navegador", + "fp_ename": "{0} elementos no se pueden mover aquí porque los nombres ya existen. Dales nuevos nombres abajo para continuar, o deja el nombre en blanco para omitirlos:", + "fcp_ename": "{0} elementos no se pueden copiar aquí porque los nombres ya existen. Dales nuevos nombres abajo para continuar, o deja el nombre en blanco para omitirlos:", + "fp_emore": "todavía quedan algunas colisiones de nombres por resolver", + "fp_ok": "movimiento correcto", + "fcp_ok": "copia correcta", + "fp_busy": "moviendo {0} elementos...\n\n{1}", + "fcp_busy": "copiando {0} elementos...\n\n{1}", + "fp_err": "fallo al mover:\n", + "fcp_err": "fallo al copiar:\n", + "fp_confirm": "¿mover estos {0} elementos aquí?", + "fcp_confirm": "¿copiar estos {0} elementos aquí?", + "fp_etab": "fallo al leer el portapapeles de otra pestaña del navegador", + "fp_name": "subiendo un archivo desde tu dispositivo. Dale un nombre:", + "fp_both_m": "
elige qué pegar
Intro = Mover {0} archivos desde «{1}»\nESC = Subir {2} archivos desde tu dispositivo", + "fcp_both_m": "
elige qué pegar
Intro = Copiar {0} archivos desde «{1}»\nESC = Subir {2} archivos desde tu dispositivo", + "fp_both_b": "MoverSubir", + "fcp_both_b": "CopiarSubir", + + "mk_noname": "escribe un nombre en el campo de texto de la izquierda antes de hacer eso :p", + + "tv_load": "Cargando documento de texto:\n\n{0}\n\n{1}% ({2} de {3} MiB cargados)", + "tv_xe1": "no se pudo cargar el archivo de texto:\n\nerror ", + "tv_xe2": "404, archivo no encontrado", + "tv_lst": "lista de archivos de texto en", + "tvt_close": "volver a la vista de carpetas$NAtajo: M (o Esc)\">❌ cerrar", + "tvt_dl": "descargar este archivo$NAtajo: Y\">💾 descargar", + "tvt_prev": "mostrar documento anterior$NAtajo: i\">⬆ ant", + "tvt_next": "mostrar siguiente documento$NAtajo: K\">⬇ sig", + "tvt_sel": "seleccionar archivo   ( para cortar / copiar / eliminar / ... )$NAtajo: S\">sel", + "tvt_edit": "abrir archivo en editor de texto$NAtajo: E\">✏️ editar", + "tvt_tail": "monitorizar cambios en el archivo; mostrar nuevas líneas en tiempo real\">📡 seguir", + "tvt_wrap": "ajuste de línea\">↵", + "tvt_atail": "bloquear el desplazamiento al final de la página\">⚓", + "tvt_ctail": "decodificar colores de terminal (códigos de escape ansi)\">🌈", + "tvt_ntail": "límite de historial (cuántos bytes de texto mantener cargados)", + + "m3u_add1": "canción añadida a la lista m3u", + "m3u_addn": "{0} canciones añadidas a la lista m3u", + "m3u_clip": "lista m3u copiada al portapapeles\n\ndebes crear un nuevo archivo de texto llamado algo.m3u y pegar la lista en ese documento; esto lo hará reproducible", + + "gt_vau": "no mostrar vídeos, solo reproducir el audio\">🎧", + "gt_msel": "activar selección de archivos; ctrl-clic en un archivo para anular$N$N<em>cuando está activo: doble clic en un archivo / carpeta para abrirlo</em>$N$NAtajo: S\">multiselección", + "gt_crop": "recortar miniaturas\">recortar", + "gt_3x": "miniaturas de alta resolución\">3x", + "gt_zoom": "zoom", + "gt_chop": "recortar", + "gt_sort": "ordenar por", + "gt_name": "nombre", + "gt_sz": "tamaño", + "gt_ts": "fecha", + "gt_ext": "tipo", + "gt_c1": "truncar más los nombres de archivo (mostrar menos)", + "gt_c2": "truncar menos los nombres de archivo (mostrar más)", + + "sm_w8": "buscando...", + "sm_prev": "los resultados de búsqueda a continuación son de una consulta anterior:\n ", + "sl_close": "cerrar resultados de búsqueda", + "sl_hits": "mostrando {0} resultados", + "sl_moar": "cargar más", + + "s_sz": "tamaño", + "s_dt": "fecha", + "s_rd": "ruta", + "s_fn": "nombre", + "s_ta": "etiquetas", + "s_ua": "subido@", + "s_ad": "avanzado", + "s_s1": "MiB mínimo", + "s_s2": "MiB máximo", + "s_d1": "mín. iso8601", + "s_d2": "máx. iso8601", + "s_u1": "subido después de", + "s_u2": "y/o antes de", + "s_r1": "la ruta contiene   (separado por espacios)", + "s_f1": "el nombre contiene   (negar con -no)", + "s_t1": "las etiquetas contienen   (^=inicio, fin=$)", + "s_a1": "propiedades de metadatos específicas", + + "md_eshow": "no se puede renderizar ", + "md_off": "[📜léeme] desactivado en [⚙️] -- documento oculto", + + "badreply": "Fallo al procesar la respuesta del servidor", + + "xhr403": "403: Acceso denegado\n\nintenta pulsar F5, quizás se cerró tu sesión", + "xhr0": "desconocido (probablemente se perdió la conexión con el servidor, o el servidor está desconectado)", + "cf_ok": "perdón por eso -- la protección DD" + wah + "oS se activó\n\nlas cosas deberían reanudarse en unos 30 segundos\n\nsi no pasa nada, pulsa F5 para recargar la página", + "tl_xe1": "no se pudieron listar las subcarpetas:\n\nerror ", + "tl_xe2": "404: Carpeta no encontrada", + "fl_xe1": "no se pudieron listar los archivos en la carpeta:\n\nerror ", + "fl_xe2": "404: Carpeta no encontrada", + "fd_xe1": "no se pudo crear la subcarpeta:\n\nerror ", + "fd_xe2": "404: Carpeta de nivel superior no encontrada", + "fsm_xe1": "no se pudo enviar el mensaje:\n\nerror ", + "fsm_xe2": "404: Carpeta de nivel superior no encontrada", + "fu_xe1": "fallo al cargar la lista de deshacer del servidor:\n\nerror ", + "fu_xe2": "404: ¿Archivo no encontrado?", + + "fz_tar": "archivo gnu-tar sin comprimir (linux / mac)", + "fz_pax": "tar formato pax sin comprimir (más lento)", + "fz_targz": "gnu-tar con compresión gzip nivel 3$N$Nesto suele ser muy lento, así que$Nusa tar sin comprimir en su lugar", + "fz_tarxz": "gnu-tar con compresión xz nivel 1$N$Nesto suele ser muy lento, así que$Nusa tar sin comprimir en su lugar", + "fz_zip8": "zip con nombres de archivo utf8 (puede dar problemas en windows 7 y anteriores)", + "fz_zipd": "zip con nombres de archivo cp437 tradicionales, para software muy antiguo", + "fz_zipc": "cp437 con crc32 calculado tempranamente,$Npara MS-DOS PKZIP v2.04g (octubre 1993)$N(tarda más en procesar antes de que la descarga pueda empezar)", + + "un_m1": "puedes eliminar tus subidas recientes (o abortar las inacabadas) a continuación", + "un_upd": "actualizar", + "un_m4": "o compartir los archivos visibles a continuación:", + "un_ulist": "mostrar", + "un_ucopy": "copiar", + "un_flt": "filtro opcional:  la URL debe contener", + "un_fclr": "limpiar filtro", + "un_derr": "fallo al deshacer-eliminar:\n", + "un_f5": "algo se rompió, por favor intenta actualizar o pulsa F5", + "un_uf5": "lo siento pero tienes que refrescar la página (por ejemplo pulsando F5 o CTRL-R) antes de que esta subida pueda ser abortada", + "un_nou": "aviso: servidor demasiado ocupado para mostrar subidas inacabadas; haz clic en el enlace \"actualizar\" en un momento", + "un_noc": "aviso: la opción de deshacer subidas completadas no está activada/permitida en la configuración del servidor", + "un_max": "mostrando los primeros 2000 archivos (usa el filtro)", + "un_avail": "{0} subidas recientes se pueden eliminar
{1} inacabadas se pueden abortar", + "un_m2": "ordenado por tiempo de subida; más recientes primero:", + "un_no1": "¡pues no! ninguna subida es suficientemente reciente", + "un_no2": "¡pues no! ninguna subida que coincida con ese filtro es suficientemente reciente", + "un_next": "eliminar los siguientes {0} archivos a continuación", + "un_abrt": "abortar", + "un_del": "eliminar", + "un_m3": "cargando tus subidas recientes...", + "un_busy": "eliminando {0} archivos...", + "un_clip": "{0} enlaces copiados al portapapeles", + + "u_https1": "deberías", + "u_https2": "cambiar a https", + "u_https3": "para un mejor rendimiento", + "u_ancient": "tu navegador es impresionantemente antiguo -- quizás deberías usar bup en su lugar", + "u_nowork": "se necesita firefox 53+ o chrome 57+ o iOS 11+", + "tail_2old": "se necesita firefox 105+ o chrome 71+ o iOS 14.5+", + "u_nodrop": "tu navegador es demasiado antiguo para subir arrastrando y soltando", + "u_notdir": "¡eso no es una carpeta!\n\ntu navegador es demasiado antiguo,\npor favor intenta arrastrar y soltar en su lugar", + "u_uri": "para arrastrar y soltar imágenes desde otras ventanas del navegador,\npor favor suéltalas sobre el gran botón de subida", + "u_enpot": "cambiar a UI ligera (puede mejorar la velocidad de subida)", + "u_depot": "cambiar a UI elegante (puede reducir la velocidad de subida)", + "u_gotpot": "cambiando a la UI ligera para mejorar la velocidad de subida,\n\n¡siéntete libre de no estar de acuerdo y volver a cambiar!", + "u_pott": "

archivos:   {0} finalizados,   {1} fallidos,   {2} ocupados,   {3} en cola

", + "u_ever": "este es el uploader básico; up2k necesita al menos
chrome 21 // firefox 13 // edge 12 // opera 12 // safari 5.1", + "u_su2k": "este es el uploader básico; up2k es mejor", + "u_uput": "optimizar para velocidad (omitir checksum)", + "u_ewrite": "no tienes acceso de escritura a esta carpeta", + "u_eread": "no tienes acceso de lectura a esta carpeta", + "u_enoi": "la búsqueda de archivos no está activada en la configuración del servidor", + "u_enoow": "sobrescribir no funcionará aquí; se necesita permiso de eliminación", + "u_badf": "Estos {0} archivos (de un total de {1}) se omitieron, posiblemente debido a permisos del sistema de archivos:\n\n", + "u_blankf": "Estos {0} archivos (de un total de {1}) están en blanco / vacíos; ¿subirlos de todos modos?\n\n", + "u_applef": "Estos {0} archivos (de un total de {1}) probablemente no son deseables;\nPulsa Aceptar/Intro para OMITIR los siguientes archivos,\nPulsa Cancelar/ESC para NO excluir, y SUBIR esos también:\n\n", + "u_just1": "\nQuizás funcione mejor si seleccionas solo un archivo", + "u_ff_many": "si usas Linux / MacOS / Android, esta cantidad de archivos podría bloquear Firefox!\nsi eso ocurre, por favor inténtalo de nuevo (o usa Chrome).", + "u_up_life": "Esta subida será eliminada del servidor\n{0} después de que se complete", + "u_asku": "subir estos {0} archivos a {1}", + "u_unpt": "puedes deshacer / eliminar esta subida usando el 🧯 de arriba a la izquierda", + "u_bigtab": "a punto de mostrar {0} archivos\n\nesto podría bloquear tu navegador, ¿estás seguro?", + "u_scan": "Escaneando archivos...", + "u_dirstuck": "el iterador de directorios se atascó intentando acceder a los siguientes {0} elementos; se omitirán:", + "u_etadone": "Hecho ({0}, {1} archivos)", + "u_etaprep": "(preparando para subir)", + "u_hashdone": "hashing completado", + "u_hashing": "hash", + "u_hs": "negociando...", + "u_started": "los archivos se están subiendo ahora; mira en [🚀]", + "u_dupdefer": "duplicado; se procesará después de todos los demás archivos", + "u_actx": "haz clic en este texto para evitar la pérdida de
rendimiento al cambiar a otras ventanas/pestañas", + "u_fixed": "¡OK!  Arreglado 👍", + "u_cuerr": "fallo al subir el trozo {0} de {1};\nprobablemente inofensivo, continuando\n\narchivo: {2}", + "u_cuerr2": "el servidor rechazó la subida (trozo {0} de {1});\nse reintentará más tarde\n\narchivo: {2}\n\nerror ", + "u_ehstmp": "se reintentará; mira abajo a la derecha", + "u_ehsfin": "el servidor rechazó la solicitud para finalizar la subida; reintentando...", + "u_ehssrch": "el servidor rechazó la solicitud para realizar la búsqueda; reintentando...", + "u_ehsinit": "el servidor rechazó la solicitud para iniciar la subida; reintentando...", + "u_eneths": "error de red al realizar la negociación de subida; reintentando...", + "u_enethd": "error de red al comprobar la existencia del destino; reintentando...", + "u_cbusy": "esperando a que el servidor vuelva a confiar en nosotros después de un fallo de red...", + "u_ehsdf": "¡el servidor se quedó sin espacio en disco!\n\nse seguirá reintentando, por si alguien\nlibera suficiente espacio para continuar", + "u_emtleak1": "parece que tu navegador podría tener una fuga de memoria;\npor favor", + "u_emtleak2": " cambia a https (recomendado) o ", + "u_emtleak3": " ", + "u_emtleakc": "prueba lo siguiente:\nLas subidas serán un poco más lentas, pero bueno.\n¡Perdón por las molestias!\n\nPD: chrome v107 tiene una solución para esto", + "u_emtleakf": "prueba lo siguiente:\n\nPD: firefox con suerte tendrá una solución en algún momento", + "u_s404": "no encontrado en el servidor", + "u_expl": "explicar", + "u_maxconn": "la mayoría de los navegadores limitan esto a 6, pero firefox te permite aumentarlo con connections-per-server en about:config", + "u_tu": '

AVISO: turbo activado,  el cliente puede no detectar y reanudar subidas incompletas; ver tooltip del botón turbo

', + "u_ts": '

AVISO: turbo activado,  los resultados de búsqueda pueden ser incorrectos; ver tooltip del botón turbo

', + "u_turbo_c": "turbo está desactivado en la configuración del servidor", + "u_turbo_g": "desactivando turbo porque no tienes\nprivilegios para listar directorios en este volumen", + "u_life_cfg": 'autoeliminar después de min (o horas)', + "u_life_est": 'la subida se eliminará ---', + "u_life_max": "esta carpeta impone una\nvida máxima de {0}", + "u_unp_ok": "se permite deshacer la subida durante {0}", + "u_unp_ng": "NO se permitirá deshacer la subida", + "ue_ro": "tu acceso a esta carpeta es de solo lectura\n\n", + "ue_nl": "actualmente no has iniciado sesión", + "ue_la": "actualmente has iniciado sesión como \"{0}\"", + "ue_sr": "actualmente estás en modo de búsqueda de archivos\n\ncambia a modo de subida haciendo clic en la lupa 🔎 (junto al gran botón BUSCAR), e intenta subir de nuevo\n\nlo siento", + "ue_ta": "intenta subir de nuevo, ahora debería funcionar", + "ue_ab": "este archivo ya se está subiendo a otra carpeta, y esa subida debe completarse antes de que el archivo pueda ser subido a otro lugar.\n\nPuedes abortar y olvidar la subida inicial usando el 🧯 de arriba a la izquierda", + "ur_1uo": "OK: Archivo subido con éxito", + "ur_auo": "OK: Todos los {0} archivos subidos con éxito", + "ur_1so": "OK: Archivo encontrado en el servidor", + "ur_aso": "OK: Todos los {0} archivos encontrados en el servidor", + "ur_1un": "Subida fallida, lo siento", + "ur_aun": "Todas las {0} subidas fallaron, lo siento", + "ur_1sn": "El archivo NO se encontró en el servidor", + "ur_asn": "Los {0} archivos NO se encontraron en el servidor", + "ur_um": "Finalizado;\n{0} subidas OK,\n{1} subidas fallidas, lo siento", + "ur_sm": "Finalizado;\n{0} archivos encontrados en el servidor,\n{1} archivos NO encontrados en el servidor", + + "lang_set": "¿refrescar para que el cambio surta efecto?" + }, + "ukr": { + "tt": "Українська", + + "cols": { + "c": "кнопки дій", + "dur": "тривалість", + "q": "якість / бітрейт", + "Ac": "аудіо кодек", + "Vc": "відео кодек", + "Fmt": "формат / контейнер", + "Ahash": "контрольна сума аудіо", + "Vhash": "контрольна сума відео", + "Res": "роздільність", + "T": "тип файлу", + "aq": "якість аудіо / бітрейт", + "vq": "якість відео / бітрейт", + "pixfmt": "підвибірка / структура пікселів", + "resw": "горизонтальна роздільність", + "resh": "вертикальна роздільність", + "chs": "аудіо канали", + "hz": "частота дискретизації" + }, + + "hks": [ + [ + "різне", + ["ESC", "закрити різні речі"], + + "файловий менеджер", + ["G", "перемкнути список / сітку"], + ["T", "перемкнути мініатюри / іконки"], + ["⇧ A/D", "розмір мініатюр"], + ["ctrl-K", "видалити вибране"], + ["ctrl-X", "вирізати до буфера"], + ["ctrl-C", "копіювати до буфера"], + ["ctrl-V", "вставити (перемістити/копіювати) сюди"], + ["Y", "завантажити вибране"], + ["F2", "перейменувати вибране"], + + "вибір файлів у списку", + ["space", "перемкнути вибір файлу"], + ["↑/↓", "перемістити курсор вибору"], + ["ctrl ↑/↓", "перемістити курсор і вікно"], + ["⇧ ↑/↓", "вибрати попередній/наступний файл"], + ["ctrl-A", "вибрати всі файли / папки"], + ], [ + "навігація", + ["B", "перемкнути хлібні крихти / панель навігації"], + ["I/K", "попередня/наступна папка"], + ["M", "батьківська папка (або згорнути поточну)"], + ["V", "перемкнути папки / текстові файли в панелі навігації"], + ["A/D", "розмір панелі навігації"], + ], [ + "аудіо плеєр", + ["J/L", "попередня/наступна пісня"], + ["U/O", "перемотати на 10сек назад/вперед"], + ["0..9", "перейти до 0%..90%"], + ["P", "відтворити/пауза (також запускає)"], + ["S", "вибрати поточну пісню"], + ["Y", "завантажити пісню"], + ], [ + "переглядач зображень", + ["J/L, ←/→", "попереднє/наступне зображення"], + ["Home/End", "перше/останнє зображення"], + ["F", "повний екран"], + ["R", "повернути за годинниковою стрілкою"], + ["⇧ R", "повернути проти годинникової стрілки"], + ["S", "вибрати зображення"], + ["Y", "завантажити зображення"], + ], [ + "відео плеєр", + ["U/O", "перемотати на 10сек назад/вперед"], + ["P/K/Space", "відтворити/пауза"], + ["C", "продовжити відтворення наступного"], + ["V", "повтор"], + ["M", "вимкнути звук"], + ["[ and ]", "встановити інтервал повтору"], + ], [ + "переглядач текстових файлів", + ["I/K", "попередній/наступний файл"], + ["M", "закрити текстовий файл"], + ["E", "редагувати текстовий файл"], + ["S", "вибрати файл (для вирізання/копіювання/перейменування)"], + ] + ], + + "m_ok": "Гаразд", + "m_ng": "Скасувати", + + "enable": "Увімкнути", + "danger": "НЕБЕЗПЕКА", + "clipped": "скопійовано до буфера обміну", + + "ht_s1": "секунда", + "ht_s2": "секунд", + "ht_m1": "хвилина", + "ht_m2": "хвилин", + "ht_h1": "година", + "ht_h2": "годин", + "ht_d1": "день", + "ht_d2": "днів", + "ht_and": " і ", + + "goh": "панель керування", + "gop": 'попередній сусід">назад', + "gou": 'батьківська папка">вгору', + "gon": 'наступна папка">далі', + "logout": "Вийти ", + "access": " доступ", + "ot_close": "закрити підменю", + "ot_search": "пошук файлів за атрибутами, шляхом / іменем, музичними тегами, або будь-якою комбінацією$N$N<code>foo bar</code> = має містити «foo» і «bar»,$N<code>foo -bar</code> = має містити «foo», але не «bar»,$N<code>^yana .opus$</code> = починатися з «yana» і бути файлом «opus»$N<code>"try unite"</code> = містити точно «try unite»$N$Nформат дати - iso-8601, наприклад$N<code>2009-12-31</code> або <code>2020-09-12 23:30:00</code>", + "ot_unpost": "скасувати: видалити недавні завантаження або перервати незавершені", + "ot_bup": "bup: основний завантажувач, підтримує навіть netscape 4.0", + "ot_mkdir": "mkdir: створити нову папку", + "ot_md": "new-md: створити новий markdown документ", + "ot_msg": "msg: надіслати повідомлення в лог сервера", + "ot_mp": "налаштування медіаплеєра", + "ot_cfg": "параметри конфігурації", + "ot_u2i": 'up2k: завантажити файли (якщо у вас є доступ для запису) або переключитися на режим пошуку, щоб побачити, чи існують вони десь на сервері$N$Nзавантаження можна поновлювати, багатопотокові, і часові мітки файлів зберігаються, але використовує більше CPU ніж [🎈]  (основний завантажувач)

під час завантаження ця іконка стає індикатором прогресу!', + "ot_u2w": 'up2k: завантажити файли з підтримкою поновлення (закрийте браузер і перетягніть ті самі файли пізніше)$N$Nбагатопотокові, і часові мітки файлів зберігаються, але використовує більше CPU ніж [🎈]  (основний завантажувач)

під час завантаження ця іконка стає індикатором прогресу!', + "ot_noie": 'Будь ласка, використовуйте Chrome / Firefox / Edge', + + "ab_mkdir": "створити папку", + "ab_mkdoc": "новий markdown документ", + "ab_msg": "надіслати повідомлення в лог сервера", + + "ay_path": "перейти до папок", + "ay_files": "перейти до файлів", + + "wt_ren": "перейменувати вибрані елементи$NГаряча клавіша: F2", + "wt_del": "видалити вибрані елементи$NГаряча клавіша: ctrl-K", + "wt_cut": "вирізати вибрані елементи <small>(потім вставити в іншому місці)</small>$NГаряча клавіша: ctrl-X", + "wt_cpy": "копіювати вибрані елементи до буфера$N(щоб вставити їх в іншому місці)$NГаряча клавіша: ctrl-C", + "wt_pst": "вставити раніше вирізане / скопійоване$NГаряча клавіша: ctrl-V", + "wt_selall": "вибрати всі файли$NГаряча клавіша: ctrl-A (коли фокус на файлі)", + "wt_selinv": "інвертувати вибір", + "wt_zip1": "завантажити цю папку як архів", + "wt_selzip": "завантажити вибір як архів", + "wt_seldl": "завантажити вибір як окремі файли$NГаряча клавіша: Y", + "wt_npirc": "копіювати інформацію треку у форматі irc", + "wt_nptxt": "копіювати інформацію треку у текстовому форматі", + "wt_m3ua": "додати до m3u плейлисту (потім клацніть 📻копіювати)", + "wt_m3uc": "копіювати m3u плейлист до буфера", + "wt_grid": "перемкнути сітку / список$NГаряча клавіша: G", + "wt_prev": "попередній трек$NГаряча клавіша: J", + "wt_play": "відтворити / пауза$NГаряча клавіша: P", + "wt_next": "наступний трек$NГаряча клавіша: L", + + "ul_par": "паралельні завантаження:", + "ut_rand": "випадкові імена файлів", + "ut_u2ts": "копіювати часову мітку останньої зміни$Nз вашої файлової системи на сервер\">📅", + "ut_ow": "перезаписати існуючі файли на сервері?$N🛡️: ніколи (замість цього створить нове ім'я файлу)$N🕒: перезаписати, якщо файл на сервері старіший за ваш$N♻️: завжди перезаписувати, якщо файли відрізняються", + "ut_mt": "продовжувати хешування інших файлів під час завантаження$N$Nможливо, вимкніть, якщо ваш CPU або HDD є вузьким місцем", + "ut_ask": 'запитати підтвердження перед початком завантаження">💭', + "ut_pot": "покращити швидкість завантаження на повільних пристроях$Nроблячи інтерфейс менш складним", + "ut_srch": "не завантажувати, а перевірити, чи файли вже $N існують на сервері (сканує всі папки, які ви можете читати)", + "ut_par": "призупинити завантаження, встановивши 0$N$Nзбільшіть, якщо ваше з'єднання повільне / висока затримка$N$Nзалишіть 1 в локальній мережі або якщо HDD сервера є вузьким місцем", + "ul_btn": "перетягніть файли / папки
(або клацніть сюди)", + "ul_btnu": "З А В А Н Т А Ж И Т И", + "ul_btns": "П О Ш У К", + + "ul_hash": "хеш", + "ul_send": "надіслати", + "ul_done": "готово", + "ul_idle1": "завантаження ще не поставлені в чергу", + "ut_etah": "середня швидкість <em>хешування</em> і орієнтовний час до завершення", + "ut_etau": "середня швидкість <em>завантаження</em> і орієнтовний час до завершення", + "ut_etat": "середня <em>загальна</em> швидкість і орієнтовний час до завершення", + + "uct_ok": "успішно завершено", + "uct_ng": "невдало: помилка / відхилено / не знайдено", + "uct_done": "ok і ng разом", + "uct_bz": "хешування або завантаження", + "uct_q": "очікує, в черзі", + + "utl_name": "ім'я файлу", + "utl_ulist": "список", + "utl_ucopy": "копіювати", + "utl_links": "посилання", + "utl_stat": "статус", + "utl_prog": "прогрес", + + // keep short: + "utl_404": "404", + "utl_err": "ПОМИЛКА", + "utl_oserr": "помилка ОС", + "utl_found": "знайдено", + "utl_defer": "відкласти", + "utl_yolo": "YOLO", + "utl_done": "готово", + + "ul_flagblk": "файли були додані до черги
однак є зайнятий up2k в іншій вкладці браузера,
тому чекаємо, поки він завершиться спочатку", + "ul_btnlk": "конфігурація сервера заблокувала цей перемикач у цьому стані", + + "udt_up": "Завантаження", + "udt_srch": "Пошук", + "udt_drop": "перетягніть сюди", + + "u_nav_m": '
гаразд, що у вас є?
Enter = Файли (один або більше)\nESC = Одна папка (включаючи підпапки)', + "u_nav_b": 'ФайлиОдна папка', + + "cl_opts": "перемикачі", + "cl_themes": "тема", + "cl_langs": "мова", + "cl_ziptype": "завантаження папки", + "cl_uopts": "перемикачі up2k", + "cl_favico": "favicon", + "cl_bigdir": "великі папки", + "cl_hsort": "#сортування", + "cl_keytype": "позначення клавіш", + "cl_hiddenc": "приховані стовпці", + "cl_hidec": "приховати", + "cl_reset": "скинути", + "cl_hpick": "натисніть на заголовки стовпців, щоб приховати їх у таблиці нижче", + "cl_hcancel": "приховання стовпців скасовано", + + "ct_grid": '田 сітка', + "ct_ttips": '◔ ◡ ◔">ℹ️ підказки', + "ct_thumb": 'у режимі сітки, перемкнути іконки або мініатюри$NГаряча клавіша: T">🖼️ мініатюри', + "ct_csel": 'використовувати CTRL і SHIFT для вибору файлів у режимі сітки">вибір', + "ct_ihop": 'коли переглядач зображень закрито, прокрутити вниз до останнього переглянутого файлу">g⮯', + "ct_dots": 'показати приховані файли (якщо сервер дозволяє)">приховані файли', + "ct_qdel": 'при видаленні файлів, запитати підтвердження лише один раз">швидке видалення', + "ct_dir1st": 'сортувати папки перед файлами">спочатку 📁', + "ct_nsort": 'природне сортування (для імен файлів з початковими цифрами)">природне сортування', + "ct_utc": 'використовуйте UTC для всіх часових позначень">UTC', //m + "ct_readme": 'показати README.md у списках папок">📜 readme', + "ct_idxh": 'показати index.html замість списку папки">htm', + "ct_sbars": 'показати смуги прокрутки">⟊', + + "cut_umod": "якщо файл вже існує на сервері, оновити часову мітку останньої зміни сервера відповідно до вашого локального файлу (потребує дозволів на запис+видалення)\">re📅", + + "cut_turbo": "кнопка yolo, ви, ймовірно, НЕ хочете її вмикати:$N$Nвикористовуйте це, якщо ви завантажували величезну кількість файлів і змушені були перезапустити з якоїсь причини, і хочете продовжити завантаження якнайшвидше$N$Nце замінює перевірку хешу простою "чи має цей файл той самий розмір на сервері?", тому якщо вміст файлу відрізняється, він НЕ буде завантажений$N$Nви повинні вимкнути це, коли завантаження буде завершено, а потім "завантажити" ті самі файли знову, щоб дозволити клієнту перевірити їх\">turbo", + + "cut_datechk": "не має ефекту, якщо кнопка turbo не ввімкнена$N$Nзменшує yolo фактор на крихту; перевіряє, чи відповідають часові мітки файлів на сервері вашим$N$Nтеоретично, повинно зловити більшість незавершених / пошкоджених завантажень, але не є заміною виконання перевірки з вимкненим turbo потім\">date-chk", + + "cut_u2sz": "розмір (у MiB) кожного фрагмента завантаження; великі значення краще летять через атлантичний океан. Спробуйте низькі значення на дуже ненадійних з'єднаннях", + + "cut_flag": "переконатися, що лише одна вкладка завантажує одночасно $N -- інші вкладки також повинні мати це ввімкнене $N -- впливає лише на вкладки на тому самому домені", + + "cut_az": "завантажувати файли в алфавітному порядку, а не від найменшого файлу$N$Nалфавітний порядок може полегшити огляд, якщо щось пішло не так на сервері, але робить завантаження трохи повільнішим на fiber / LAN", + + "cut_nag": "сповіщення ОС після завершення завантаження$N(тільки якщо браузер або вкладка не активні)", + "cut_sfx": "звуковий сигнал після завершення завантаження$N(тільки якщо браузер або вкладка не активні)", + + "cut_mt": "використовувати багатопотоковість для прискорення хешування файлів$N$Nце використовує веб-воркери і потребує$Nбільше пам'яті (до 512 MiB додатково)$N$Nробить https на 30% швидше, http у 4.5 рази швидше\">mt", + + "cut_wasm": "використовувати wasm замість вбудованого хешера браузера; покращує швидкість у браузерах на базі chrome, але збільшує навантаження CPU, плюс багато старих версій chrome мають баги, які змушують браузер споживати всю пам'ять і вилітати, якщо ця опція ввімкненаа\">wasm", + + "cft_text": "текст favicon (порожній і оновити для відключення)", + "cft_fg": "колір переднього плану", + "cft_bg": "колір фону", + + "cdt_lim": "максимальна кількість файлів для показу в папці", + "cdt_ask": "при прокрутці до низу,$Nзамість завантаження більше файлів,$Nзапитати, що робити", + "cdt_hsort": "скільки правил сортування (<code>,sorthref</code>) включати в медіа-URL. Встановлення цього в 0 також буде ігнорувати правила сортування, включені в медіа посилання при їх натисканні", + + "tt_entree": "показати панель навігації (бічна панель дерева каталогів)$NГаряча клавіша: B", + "tt_detree": "показати хлібні крихти$NГаряча клавіша: B", + "tt_visdir": "прокрутити до вибраної папки", + "tt_ftree": "перемкнути дерево папок / текстові файли$NГаряча клавіша: V", + "tt_pdock": "показати батьківські папки в закріпленій панелі зверху", + "tt_dynt": "автоматично збільшуватися при розширенні дерева", + "tt_wrap": "перенесення слів", + "tt_hover": "показувати переповнені рядки при наведенні$N( порушує прокрутку, якщо курсор $N  миші не знаходиться в лівому відступі )", + + "ml_pmode": "в кінці папки...", + "ml_btns": "команди", + "ml_tcode": "транскодувати", + "ml_tcode2": "транскодувати в", + "ml_tint": "відтінок", + "ml_eq": "аудіо еквалайзер", + "ml_drc": "компресор динамічного діапазону", + + "mt_loop": "зациклити/повторити одну пісню\">🔁", + "mt_one": "зупинити після однієї пісні\">1️⃣", + "mt_shuf": "перемішати пісні в кожній папці\">🔀", + "mt_aplay": "автовідтворення, якщо є ID пісні в посиланні, по якому ви клацнули для доступу до сервера$N$Nвідключення цього також зупинить оновлення URL сторінки з ID пісень під час відтворення музики, щоб запобігти автовідтворенню, якщо ці налаштування втрачені, але URL залишається\">a▶", + "mt_preload": "почати завантаження наступної пісні ближче до кінця для безперервного відтворення\">preload", + "mt_prescan": "перейти до наступної папки перед тим, як остання пісня$Nзакінчиться, підтримуючи веб-браузер у робочому стані$Nщоб він не зупинив відтворення\">nav", + "mt_fullpre": "спробувати попередньо завантажити всю пісню;$N✅ увімкніть на ненадійних з'єднаннях,$N❌ вимкніть на повільних з'єднаннях, ймовірно\">full", + "mt_fau": "на телефонах, запобігти зупинці музики, якщо наступна пісня не завантажується достатньо швидко (може зробити відображення тегів глючним)\">☕️", + "mt_waves": "смуга хвильової форми:$Nпоказати амплітуду аудіо в повзунку\">~s", + "mt_npclip": "показати кнопки для копіювання до буфера поточної пісні, що відтворюється\">/np", + "mt_m3u_c": "показати кнопки для копіювання до буфера$Nвибраних пісень як записи плейлисту m3u8\">📻", + "mt_octl": "інтеграція з ОС (медіа гарячі клавіші / osd)\">os-ctl", + "mt_oseek": "дозволити перемотування через інтеграцію з ОС$N$Nзауваження: на деяких пристроях (iPhone),$Nце замінює кнопку наступної пісні\">seek", + "mt_oscv": "показати обкладинку альбому в osd\">art", + "mt_follow": "тримати трек, що відтворюється, у полі зору\">🎯", + "mt_compact": "компактні елементи керування\">⟎", + "mt_uncache": "очистити кеш  (спробуйте це, якщо ваш браузер закешував$Nпошкоджену копію пісні, тому відмовляється її відтворювати)\">uncache", + "mt_mloop": "зациклити відкриту папку\">🔁 loop", + "mt_mnext": "завантажити наступну папку і продовжити\">📂 next", + "mt_mstop": "зупинити відтворення\">⏸ stop", + "mt_cflac": "конвертувати flac / wav в opus\">flac", + "mt_caac": "конвертувати aac / m4a в opus\">aac", + "mt_coth": "конвертувати всі інші (не mp3) в opus\">oth", + "mt_c2opus": "найкращий вибір для робочих столів, ноутбуків, android\">opus", + "mt_c2owa": "opus-weba, для iOS 17.5 і новіших\">owa", + "mt_c2caf": "opus-caf, для iOS 11 до 17\">caf", + "mt_c2mp3": "використовуйте це на дуже старих пристроях\">mp3", + "mt_c2ok": "гарно, хороший вибір", + "mt_c2nd": "це не рекомендований вихідний формат для вашого пристрою, але це нормально", + "mt_c2ng": "ваш пристрій, здається, не підтримує цей вихідний формат, але давайте все одно спробуємо", + "mt_xowa": "є баги в iOS, які запобігають фоновому відтворенню з використанням цього формату; будь ласка, використовуйте caf або mp3 замість цього", + "mt_tint": "рівень фону (0-100) на смузі перемотування$Nщоб зробити буферизацію менш відвертаючою", + "mt_eq": "вмикає еквалайзер і контроль посилення;$N$Nпосилення <code>0</code> = стандартна 100% гучність (немодифікована)$N$Nширина <code>1  </code> = стандартне стерео (немодифіковане)$Nширина <code>0.5</code> = 50% перехресне живлення ліво-право$Nширина <code>0  </code> = моно$N$Nпосилення <code>-0.8</code> & ширина <code>10</code> = видалення вокалу :^)$N$Nвключення еквалайзера робить безшовні альбоми повністю безшовними, тому залишайте його увімкненим з усіма значеннями в нулі (окрім ширини = 1), якщо вам це важливо", + "mt_drc": "вмикає компресор динамічного діапазону (вирівнювач гучності / цегловий вал); також увімкне EQ для балансування спагеті, тому встановіть всі поля EQ окрім 'width' в 0, якщо ви цього не хочете$N$Nзнижує гучність аудіо вище THRESHOLD дБ; для кожного RATIO дБ понад THRESHOLD є 1 дБ виходу, тому стандартні значення tresh -24 і ratio 12 означають, що він ніколи не повинен стати гучнішим за -22 дБ і безпечно збільшити посилення еквалайзера до 0.8, або навіть 1.8 з ATK 0 і величезним RLS як 90 (працює тільки в firefox; RLS максимум 1 в інших браузерах)$N$N(дивіться вікіпедію, вони пояснюють це набагато краще)", + + "mb_play": "відтворити", + "mm_hashplay": "відтворити цей аудіо файл?", + "mm_m3u": "натисніть Enter/OK для відтворення\nнатисніть ESC/Cancel для редагування", + "mp_breq": "потрібен firefox 82+ або chrome 73+ або iOS 15+", + "mm_bload": "зараз завантажується...", + "mm_bconv": "конвертується в {0}, будь ласка, зачекайте...", + "mm_opusen": "ваш браузер не може відтворювати aac / m4a файли;\nтранскодування в opus тепер увімкнено", + "mm_playerr": "відтворення невдале: ", + "mm_eabrt": "Спроба відтворення була скасована", + "mm_enet": "Ваше інтернет-з'єднання нестабільне", + "mm_edec": "Цей файл нібито пошкоджений??", + "mm_esupp": "Ваш браузер не розуміє цей аудіо формат", + "mm_eunk": "Невідома помилка", + "mm_e404": "Не вдалося відтворити аудіо; помилка 404: Файл не знайдено.", + "mm_e403": "Не вдалося відтворити аудіо; помилка 403: Доступ заборонено.\n\nСпробуйте натиснути F5 для перезавантаження, можливо, ви вийшли з системи", + "mm_e500": "Не вдалося відтворити аудіо; помилка 500: Перевірте логи сервера.", + "mm_e5xx": "Не вдалося відтворити аудіо; помилка сервера ", + "mm_nof": "не знаходжу більше аудіо файлів поблизу", + "mm_prescan": "Шукаю музику для наступного відтворення...", + "mm_scank": "Знайшов наступну пісню:", + "mm_uncache": "кеш очищено; всі пісні будуть перезавантажені при наступному відтворенні", + "mm_hnf": "ця пісня більше не існує", + + "im_hnf": "це зображення більше не існує", + + "f_empty": 'ця папка порожня', + "f_chide": 'це приховає стовпець «{0}»\n\nви можете показати стовпці в вкладці налаштувань', + "f_bigtxt": "цей файл розміром {0} MiB -- дійсно переглядати як текст?", + "f_bigtxt2": "переглянути лише кінець файлу замість цього? це також увімкне відслідковування/tailing, показуючи новододані рядки тексту в реальному часі", + "fbd_more": '
показано {0} з {1} файлів; показати {2} або показати всі
', + "fbd_all": '
показано {0} з {1} файлів; показати всі
', + "f_anota": "лише {0} з {1} елементів було вибрано;\nщоб вибрати всю папку, спочатку прокрутіть до низу", + + "f_dls": 'посилання на файли в поточній папці були\nзмінені на посилання для завантаження', + + "f_partial": "Щоб безпечно завантажити файл, який зараз завантажується, будь ласка, клацніть на файл, який має таке саме ім'я, але без розширення .PARTIAL. Будь ласка, натисніть CANCEL або Escape, щоб зробити це.\n\nНатиснення OK / Enter проігнорує це попередження і продовжить завантаження .PARTIAL робочого файлу замість цього, що майже напевно дасть вам пошкоджені дані.", + + "ft_paste": "вставити {0} елементів$NГаряча клавіша: ctrl-V", + "fr_eperm": 'не можу перейменувати:\nу вас немає дозволу “переміщення“ в цій папці', + "fd_eperm": 'не можу видалити:\nу вас немає дозволу “видалення“ в цій папці', + "fc_eperm": 'не можу вирізати:\nу вас немає дозволу “переміщення“ в цій папці', + "fp_eperm": 'не можу вставити:\nу вас немає дозволу “запису“ в цій папці', + "fr_emore": "виберіть принаймні один елемент для перейменування", + "fd_emore": "виберіть принаймні один елемент для видалення", + "fc_emore": "виберіть принаймні один елемент для вирізання", + "fcp_emore": "виберіть принаймні один елемент для копіювання до буфера", + + "fs_sc": "поділитися папкою, в якій ви знаходитесь", + "fs_ss": "поділитися вибраними файлами", + "fs_just1d": "ви не можете вибрати більше однієї папки,\nабо змішувати файли і папки в одному виборі", + "fs_abrt": "❌ скасувати", + "fs_rand": "🎲 випадк.ім'я", + "fs_go": "✅ створити спільний доступ", + "fs_name": "ім'я", + "fs_src": "джерело", + "fs_pwd": "пароль", + "fs_exp": "термін дії", + "fs_tmin": "хв", + "fs_thrs": "годин", + "fs_tdays": "днів", + "fs_never": "вічний", + "fs_pname": "необов'язкове ім'я посилання; буде випадковим, якщо порожнє", + "fs_tsrc": "файл або папка для спільного доступу", + "fs_ppwd": "необов'язковий пароль", + "fs_w8": "створення спільного доступу...", + "fs_ok": "натисніть Enter/OK для копіювання до буфера\nнатисніть ESC/Cancel для закриття", + + "frt_dec": "може виправити деякі випадки пошкоджених імен файлів\">url-decode", + "frt_rst": "скинути змінені імена файлів назад до оригінальних\">↺ reset", + "frt_abrt": "перервати і закрити це вікно\">❌ cancel", + "frb_apply": "ЗАСТОСУВАТИ ПЕРЕЙМЕНУВАННЯ", + "fr_adv": "пакетне / метадані / шаблонне перейменування\">розширене", + "fr_case": "регулярний вираз з урахуванням регістру\">регістр", + "fr_win": "безпечні для windows імена; замінити <>:"\\|?* на японські повноширинні символи\">win", + "fr_slash": "замінити / на символ, який не призводить до створення нових папок\">без /", + "fr_re": "шаблон пошуку регулярного виразу для застосування до оригінальних імен файлів; групи захоплення можна посилатися в полі формату нижче як <code>(1)</code> і <code>(2)</code> і так далі", + "fr_fmt": "натхненний foobar2000:$N<code>(title)</code> замінюється назвою пісні,$N<code>[(artist) - ](title)</code> пропускає [цю] частину, якщо виконавець порожній$N<code>$lpad((tn),2,0)</code> доповнює номер треку до 2 цифр", + "fr_pdel": "видалити", + "fr_pnew": "зберегти як", + "fr_pname": "надайте ім'я для вашого нового пресету", + "fr_aborted": "перервано", + "fr_lold": "старе ім'я", + "fr_lnew": "нове ім'я", + "fr_tags": "теги для вибраних файлів (тільки для читання, лише для довідки):", + "fr_busy": "перейменування {0} елементів...\n\n{1}", + "fr_efail": "перейменування невдале:\n", + "fr_nchg": "{0} з нових імен були змінені через win та/або no /\n\nOK продовжити з цими зміненими новими іменами?", + + "fd_ok": "видалення OK", + "fd_err": "видалення невдале:\n", + "fd_none": "нічого не було видалено; можливо, заблоковано конфігурацією сервера (xbd)?", + "fd_busy": "видалення {0} елементів...\n\n{1}", + "fd_warn1": "ВИДАЛИТИ ці {0} елементи?", + "fd_warn2": "Останній шанс! Неможливо скасувати. Видалити?", + + "fc_ok": "вирізано {0} елементів", + "fc_warn": 'вирізано {0} елементів\n\nале: тільки ця вкладка браузера може їх вставити\n(оскільки вибір настільки величезний)', + + "fcc_ok": "скопійовано {0} елементів до буфера", + "fcc_warn": 'скопійовано {0} елементів до буфера\n\nале: тільки ця вкладка браузера може їх вставити\n(оскільки вибір настільки величезний)', + + "fp_apply": "використовувати ці імена", + "fp_ecut": "спочатку вирізати або скопіювати деякі файли / папки для вставки / переміщення\n\nзауваження: ви можете вирізати / вставляти через різні вкладки браузера", + "fp_ename": "{0} елементів не можуть бути переміщені сюди, тому що імена вже зайняті. Дайте їм нові імена нижче для продовження, або залиште ім'я порожнім, щоб пропустити їх:", + "fcp_ename": "{0} елементів не можуть бути скопійовані сюди, тому що імена вже зайняті. Дайте їм нові імена нижче для продовження, або залиште ім'я порожнім, щоб пропустити їх:", + "fp_emore": "є ще деякі конфлікти імен файлів, які потрібно виправити", + "fp_ok": "переміщення OK", + "fcp_ok": "копіювання OK", + "fp_busy": "переміщення {0} елементів...\n\n{1}", + "fcp_busy": "копіювання {0} елементів...\n\n{1}", + "fp_err": "переміщення невдале:\n", + "fcp_err": "копіювання невдале:\n", + "fp_confirm": "перемістити ці {0} елементи сюди?", + "fcp_confirm": "скопіювати ці {0} елементи сюди?", + "fp_etab": 'не вдалося прочитати буфер з іншої вкладки браузера', + "fp_name": "завантаження файлу з вашого пристрою. Дайте йому ім'я:", + "fp_both_m": '
виберіть, що вставити
Enter = Перемістити {0} файлів з «{1}»\nESC = Завантажити {2} файлів з вашого пристрою', + "fcp_both_m": '
виберіть, що вставити
Enter = Скопіювати {0} файлів з «{1}»\nESC = Завантажити {2} файлів з вашого пристрою', + "fp_both_b": 'ПереміститиЗавантажити', + "fcp_both_b": 'СкопіюватиЗавантажити', + + "mk_noname": "введіть ім'я в текстове поле зліва перед тим, як робити це :p", + + "tv_load": "Завантаження текстового документа:\n\n{0}\n\n{1}% ({2} з {3} MiB завантажено)", + "tv_xe1": "не вдалося завантажити текстовий файл:\n\nпомилка ", + "tv_xe2": "404, файл не знайдено", + "tv_lst": "список текстових файлів в", + "tvt_close": "повернутися до перегляду папки$NГаряча клавіша: M (або Esc)\">❌ закрити", + "tvt_dl": "завантажити цей файл$NГаряча клавіша: Y\">💾 завантажити", + "tvt_prev": "показати попередній документ$NГаряча клавіша: i\">⬆ попер", + "tvt_next": "показати наступний документ$NГаряча клавіша: K\">⬇ наст", + "tvt_sel": "вибрати файл   ( для вирізання / копіювання / видалення / ... )$NГаряча клавіша: S\">вибр", + "tvt_edit": "відкрити файл в текстовому редакторі$NГаряча клавіша: E\">✏️ редагувати", + "tvt_tail": "моніторити файл на зміни; показувати нові рядки в реальному часі\">📡 слідкувати", + "tvt_wrap": "перенесення слів\">↵", + "tvt_atail": "заблокувати прокрутку до низу сторінки\">⚓", + "tvt_ctail": "декодувати кольори терміналу (ansi escape коди)\">🌈", + "tvt_ntail": "ліміт історії прокрутки (скільки байтів тексту тримати завантаженими)", + + "m3u_add1": "пісня додана до m3u плейлисту", + "m3u_addn": "{0} пісень додано до m3u плейлисту", + "m3u_clip": "m3u плейлист тепер скопійований до буфера\n\nви повинні створити новий текстовий файл з назвою щось.m3u і вставити плейлист в цей документ; це зробить його відтворюваним", + + "gt_vau": "не показувати відео, лише відтворювати аудіо\">🎧", + "gt_msel": "увімкнути вибір файлів; ctrl-клік по файлу для перевизначення$N$N<em>коли активний: подвійний клік по файлу / папці щоб відкрити</em>$N$NГаряча клавіша: S\">мультивибір", + "gt_crop": "обрізати мініатюри по центру\">обрізка", + "gt_3x": "мініатюри високої роздільності\">3x", + "gt_zoom": "масштаб", + "gt_chop": "обрізати", + "gt_sort": "сортувати за", + "gt_name": "ім'ям", + "gt_sz": "розміром", + "gt_ts": "датою", + "gt_ext": "типом", + "gt_c1": "обрізати імена файлів більше (показувати менше)", + "gt_c2": "обрізати імена файлів менше (показувати більше)", + + "sm_w8": "пошук...", + "sm_prev": "результати пошуку нижче з попереднього запиту:\n ", + "sl_close": "закрити результати пошуку", + "sl_hits": "показано {0} результатів", + "sl_moar": "завантажити більше", + + "s_sz": "розмір", + "s_dt": "дата", + "s_rd": "шлях", + "s_fn": "ім'я", + "s_ta": "теги", + "s_ua": "up@", + "s_ad": "розш.", + "s_s1": "мінімум MiB", + "s_s2": "максимум MiB", + "s_d1": "мін. iso8601", + "s_d2": "макс. iso8601", + "s_u1": "завантажено після", + "s_u2": "та/або до", + "s_r1": "шлях містить   (розділені пробілами)", + "s_f1": "ім'я містить   (заперечення з -ні)", + "s_t1": "теги містять   (^=початок, кінець=$)", + "s_a1": "специфічні властивості метаданих", + + "md_eshow": "не можу відобразити ", + "md_off": "[📜readme] відключено в [⚙️] -- документ прихований", + + "badreply": "Не вдалося обробити відповідь сервера", + + "xhr403": "403: Доступ заборонено\n\nспробуйте натиснути F5, можливо ви вийшли з системи", + "xhr0": "невідома (ймовірно втрачено з'єднання з сервером, або сервер офлайн)", + "cf_ok": "вибачте за це -- захист від DD" + "oS спрацював\n\nречі повинні відновитися приблизно через 30 сек\n\nякщо нічого не відбувається, натисніть F5 для перезавантаження сторінки", + "tl_xe1": "не вдалося перелічити підпапки:\n\nпомилка ", + "tl_xe2": "404: Папка не знайдена", + "fl_xe1": "не вдалося перелічити файли в папці:\n\nпомилка ", + "fl_xe2": "404: Папка не знайдена", + "fd_xe1": "не вдалося створити підпапку:\n\nпомилка ", + "fd_xe2": "404: Батьківська папка не знайдена", + "fsm_xe1": "не вдалося надіслати повідомлення:\n\nпомилка ", + "fsm_xe2": "404: Батьківська папка не знайдена", + "fu_xe1": "не вдалося завантажити список unpost з сервера:\n\nпомилка ", + "fu_xe2": "404: Файл не знайдено??", + + "fz_tar": "нестиснутий gnu-tar файл (linux / mac)", + "fz_pax": "нестиснутий tar в pax-форматі (повільніше)", + "fz_targz": "gnu-tar зі стисненням gzip рівня 3$N$Nце зазвичай дуже повільно, тому$Nвикористовуйте нестиснутий tar замість цього", + "fz_tarxz": "gnu-tar зі стисненням xz рівня 1$N$Nце зазвичай дуже повільно, тому$Nвикористовуйте нестиснутий tar замість цього", + "fz_zip8": "zip з utf8 іменами файлів (можливо нестабільний на windows 7 і старіших)", + "fz_zipd": "zip з традиційними cp437 іменами файлів, для дуже старого ПЗ", + "fz_zipc": "cp437 з crc32, обчисленим заздалегідь,$Nдля MS-DOS PKZIP v2.04g (жовтень 1993)$N(потребує більше часу для обробки перед початком завантаження)", + + "un_m1": "ви можете видалити ваші недавні завантаження (або перервати незавершені) нижче", + "un_upd": "оновити", + "un_m4": "або поділитися файлами, видимими нижче:", + "un_ulist": "показати", + "un_ucopy": "копіювати", + "un_flt": "необов'язковий фільтр:  URL повинен містити", + "un_fclr": "очистити фільтр", + "un_derr": 'unpost-видалення невдале:\n', + "un_f5": 'щось зламалося, будь ласка, спробуйте оновити або натисніть F5', + "un_uf5": "вибачте, але ви повинні оновити сторінку (наприклад, натиснувши F5 або CTRL-R) перед тим, як це завантаження можна буде перервати", + "un_nou": 'попередження: сервер занадто зайнятий, щоб показати незавершені завантаження; клацніть посилання "оновити" трохи пізніше', + "un_noc": 'попередження: unpost повністю завантажених файлів не увімкнено/дозволено в конфігурації сервера', + "un_max": "показано перші 2000 файлів (використовуйте фільтр)", + "un_avail": "{0} недавніх завантажень можуть бути видалені
{1} незавершених можуть бути перервані", + "un_m2": "відсортовано за часом завантаження; найновіші спочатку:", + "un_no1": "ха! немає завантажень, достатньо недавніх", + "un_no2": "ха! немає завантажень, що відповідають цьому фільтру, достатньо недавніх", + "un_next": "видалити наступні {0} файлів нижче", + "un_abrt": "перервати", + "un_del": "видалити", + "un_m3": "завантаження ваших недавніх завантажень...", + "un_busy": "видалення {0} файлів...", + "un_clip": "{0} посилань скопійовано до буфера", + + "u_https1": "вам слід", + "u_https2": "переключитися на https", + "u_https3": "для кращої продуктивності", + "u_ancient": 'ваш браузер вражаюче старий -- можливо, вам слід використовувати bup замість цього', + "u_nowork": "потрібен firefox 53+ або chrome 57+ або iOS 11+", + "tail_2old": "потрібен firefox 105+ або chrome 71+ або iOS 14.5+", + "u_nodrop": 'ваш браузер занадто старий для перетягування завантажень', + "u_notdir": "це не папка!\n\nваш браузер занадто старий,\nбудь ласка, спробуйте перетягування замість цього", + "u_uri": "щоб перетягнути зображення з інших вікон браузера,\nбудь ласка, перетягніть його на велику кнопку завантаження", + "u_enpot": 'переключитися на картоплинний UI (може покращити швидкість завантаження)', + "u_depot": 'переключитися на вишуканий UI (може зменшити швидкість завантаження)', + "u_gotpot": 'переключення на картоплинний UI для покращення швидкості завантаження,\n\nне соромтеся не погодитися і переключитися назад!', + "u_pott": "

файли:   {0} завершено,   {1} невдало,   {2} зайнято,   {3} в черзі

", + "u_ever": "це базовий завантажувач; up2k потребує принаймні
chrome 21 // firefox 13 // edge 12 // opera 12 // safari 5.1", + "u_su2k": 'це базовий завантажувач; up2k кращий', + "u_uput": 'оптимізувати для швидкості (пропустити контрольну суму)', + "u_ewrite": 'у вас немає доступу для запису в цю папку', + "u_eread": 'у вас немає доступу для читання цієї папки', + "u_enoi": 'пошук файлів не увімкнено в конфігурації сервера', + "u_enoow": "перезапис не працюватиме тут; потрібен дозвіл на видалення", + "u_badf": 'Ці {0} файли (з {1} загальних) були пропущені, можливо, через дозволи файлової системи:\n\n', + "u_blankf": 'Ці {0} файли (з {1} загальних) порожні; все одно завантажити їх?\n\n', + "u_applef": 'Ці {0} файли (з {1} загальних), ймовірно, небажані;\nНатисніть OK/Enter щоб ПРОПУСТИТИ наступні файли,\nНатисніть Cancel/ESC щоб НЕ виключати, і ЗАВАНТАЖИТИ їх також:\n\n', + "u_just1": '\nМожливо, це спрацює краще, якщо ви виберете лише один файл', + "u_ff_many": "якщо ви використовуєте Linux / MacOS / Android, то така кількість файлів може завісити Firefox!\nякщо це станеться, будь ласка, спробуйте знову (або використовуйте Chrome).", + "u_up_life": "Це завантаження буде видалено з сервера\n{0} після його завершення", + "u_asku": 'завантажити ці {0} файлів до {1}', + "u_unpt": "ви можете скасувати / видалити це завантаження, використовуючи 🧯 зверху зліва", + "u_bigtab": 'збираюся показати {0} файлів\n\nце може завісити ваш браузер, ви впевнені?', + "u_scan": 'Сканування файлів...', + "u_dirstuck": 'ітератор каталогу застряг, намагаючись отримати доступ до наступних {0} елементів; пропущу:', + "u_etadone": 'Готово ({0}, {1} файлів)', + "u_etaprep": '(підготовка до завантаження)', + "u_hashdone": 'хешування завершено', + "u_hashing": 'хешування', + "u_hs": 'рукостискання...', + "u_started": "файли тепер завантажуються; дивіться [🚀]", + "u_dupdefer": "дублікат; буде оброблено після всіх інших файлів", + "u_actx": "клацніть цей текст, щоб запобігти втраті
продуктивності при переключенні на інші вікна/вкладки", + "u_fixed": "OK!  Виправлено 👍", + "u_cuerr": "не вдалося завантажити фрагмент {0} з {1};\nймовірно, нешкідливо, продовжую\n\nфайл: {2}", + "u_cuerr2": "сервер відхилив завантаження (фрагмент {0} з {1});\nспробую пізніше\n\nфайл: {2}\n\nпомилка ", + "u_ehstmp": "спробую знову; дивіться внизу справа", + "u_ehsfin": "сервер відхилив запит на завершення завантаження; повторюю...", + "u_ehssrch": "сервер відхилив запит на виконання пошуку; повторюю...", + "u_ehsinit": "сервер відхилив запит на ініціацію завантаження; повторюю...", + "u_eneths": "мережева помилка під час виконання рукостискання завантаження; повторюю...", + "u_enethd": "мережева помилка під час тестування існування цілі; повторюю...", + "u_cbusy": "чекаємо, поки сервер знову нам довірятиме після мережевого збою...", + "u_ehsdf": "на сервері закінчилося місце на диску!\n\nбуду продовжувати спроби, на випадок, якщо хтось\nзвільнить достатньо місця для продовження", + "u_emtleak1": "схоже, ваш веб-браузер може мати витік пам'яті;\nбудь ласка,", + "u_emtleak2": ' переключіться на https (рекомендується) або ', + "u_emtleak3": ' ', + "u_emtleakc": 'спробуйте наступне:\nЗавантаження будуть трохи повільнішими, але що поробиш.\nВибачте за незручності !\n\nPS: chrome v107 має виправлення для цього', + "u_emtleakf": 'спробуйте наступне:\n\nPS: firefox сподіваємося, матиме виправлення в якийсь момент', + "u_s404": "не знайдено на сервері", + "u_expl": "пояснити", + "u_maxconn": "більшість браузерів обмежують це до 6, але firefox дозволяє підвищити це з connections-per-server в about:config", + "u_tu": '

ПОПЕРЕДЖЕННЯ: turbo увімкнено,  клієнт може не виявити і поновити неповні завантаження; дивіться підказку turbo-кнопки

', + "u_ts": '

ПОПЕРЕДЖЕННЯ: turbo увімкнено,  результати пошуку можуть бути неправильними; дивіться підказку turbo-кнопки

', + "u_turbo_c": "turbo відключено в конфігурації сервера", + "u_turbo_g": "відключаю turbo, тому що у вас немає\nпривілеїв перегляду каталогів в цьому томі", + "u_life_cfg": 'автовидалення через хв (або годин)', + "u_life_est": 'завантаження буде видалено ---', + "u_life_max": 'ця папка забезпечує\nмакс. термін життя {0}', + "u_unp_ok": 'unpost дозволено для {0}', + "u_unp_ng": 'unpost НЕ буде дозволено', + "ue_ro": 'ваш доступ до цієї папки тільки для читання\n\n', + "ue_nl": 'ви зараз не увійшли в систему', + "ue_la": 'ви зараз увійшли як "{0}"', + "ue_sr": 'ви зараз в режимі пошуку файлів\n\nпереключіться на режим завантаження, клацнувши лупу 🔎 (поруч з великою кнопкою ПОШУК), і спробуйте завантажити знову\n\nвибачте', + "ue_ta": 'спробуйте завантажити знову, це повинно спрацювати зараз', + "ue_ab": "цей файл вже завантажується в іншу папку, і це завантаження повинно бути завершено перед тим, як файл можна буде завантажити в інше місце.\n\nВи можете перервати і забути початкове завантаження, використовуючи 🧯 зверху зліва", + "ur_1uo": "OK: Файл успішно завантажено", + "ur_auo": "OK: Всі {0} файлів успішно завантажено", + "ur_1so": "OK: Файл знайдено на сервері", + "ur_aso": "OK: Всі {0} файлів знайдено на сервері", + "ur_1un": "Завантаження невдале, вибачте", + "ur_aun": "Всі {0} завантажень невдалі, вибачте", + "ur_1sn": "Файл НЕ знайдено на сервері", + "ur_asn": "{0} файлів НЕ знайдено на сервері", + "ur_um": "Завершено;\n{0} завантажень OK,\n{1} завантажень невдалих, вибачте", + "ur_sm": "Завершено;\n{0} файлів знайдено на сервері,\n{1} файлів НЕ знайдено на сервері", + + "lang_set": "оновити сторінку, щоб зміни набули чинності?", + }, }; -var LANGS = ["eng", "nor", "chi"]; +var LANGS = ["eng", "nor", "chi", "deu", "fin", "rus", "spa", "ukr"]; if (window.langmod) langmod(); @@ -2102,6 +5239,7 @@ ebi('op_cfg').innerHTML = ( ' ' + sv; } - ln = ln.concat([tn.ext, unix2iso(tn.ts)]).join(''); + ln = ln.concat([tn.ext, unix2ui(tn.ts)]).join(''); html.push(ln + ''); } html.push(''); @@ -10022,29 +13164,19 @@ var unpost = (function () { return ebi('op_unpost').innerHTML = '

' + L.badreply + ':

' + unpre(this.responseText); } - if (ores.u.length == 1 && ores.u[0].timeout) { + if (ores.nou) html.push('

' + L.un_nou + '

'); - ores.u = []; - } - if (ores.c.length == 1 && ores.c[0].kinshi) { + if (ores.noc) html.push('

' + L.un_noc + '

'); - ores.c = []; - } - for (var a = 0; a < ores.u.length; a++) - ores.u[a].k = 'u'; - - for (var a = 0; a < ores.c.length; a++) - ores.c[a].k = 'c'; - - var res = ores.u.concat(ores.c); + var res = ores.f; if (res.length) { - if (res.length == 2000) + if (ores.of) html.push("

" + L.un_max); else - html.push("

" + L.un_avail.format(ores.c.length, ores.u.length)); + html.push("

" + L.un_avail.format(ores.nc, ores.nu)); html.push("
" + L.un_m2 + "

"); html.push(""); @@ -10061,10 +13193,10 @@ var unpost = (function () { '' + L.un_next.format(Math.min(mods[b], res.length - a)) + ''); - var done = res[a].k == 'c'; + var done = res[a].pd === undefined; html.push( '' + - '' + + '' + '' + (done ? '' : '') + ''); diff --git a/copyparty/web/rups.html b/copyparty/web/rups.html index 5d286cae..af90eefe 100644 --- a/copyparty/web/rups.html +++ b/copyparty/web/rups.html @@ -33,6 +33,7 @@ var SR="{{ r }}", lang="{{ lang }}", + dutc={{ this.args.js_utc }}, dfavico="{{ favico }}"; var STG = window.localStorage; diff --git a/copyparty/web/rups.js b/copyparty/web/rups.js index e476f0fe..9559be8c 100644 --- a/copyparty/web/rups.js +++ b/copyparty/web/rups.js @@ -10,7 +10,7 @@ function render() { fn = esc(uricom_dec(vsp[1])), at = f.at, td = now - f.at, - ts = !at ? '(?)' : unix2iso(at), + ts = !at ? '(?)' : unix2ui(at), sa = !at ? '(?)' : td > 60 ? shumantime(td) : (td + 's'), sz = ('' + f.sz).replace(/\B(?=(\d{3})+(?!\d))/g, " "); diff --git a/copyparty/web/shares.html b/copyparty/web/shares.html index 9c7dcd27..381fe853 100644 --- a/copyparty/web/shares.html +++ b/copyparty/web/shares.html @@ -66,6 +66,7 @@ var SR="{{ r }}", shr="{{ shr }}", lang="{{ lang }}", + dutc={{ this.args.js_utc }}, dfavico="{{ favico }}"; var STG = window.localStorage; diff --git a/copyparty/web/shares.js b/copyparty/web/shares.js index 86d4cc45..d14dfeb7 100644 --- a/copyparty/web/shares.js +++ b/copyparty/web/shares.js @@ -1,9 +1,11 @@ +var SRS = SR.trimEnd('/') + '/'; + var t = QSA('a[k]'); for (var a = 0; a < t.length; a++) t[a].onclick = rm; function rm() { - var u = SR + shr + uricom_enc(this.getAttribute('k')) + '?eshare=rm', + var u = SRS + '?eshare=rm&skey=' + uricom_enc(this.getAttribute('k')), xhr = new XHR(); xhr.open('POST', u, true); @@ -13,7 +15,7 @@ function rm() { function bump() { var k = this.closest('tr').getElementsByTagName('a')[2].getAttribute('k'), - u = SR + shr + uricom_enc(k) + '?eshare=' + this.value, + u = SRS + '?skey=' + uricom_enc(k) + '&eshare=' + this.value, xhr = new XHR(); xhr.open('POST', u, true); @@ -64,7 +66,7 @@ function showqr(href) { for (var b = 7; b < 9; b++) { var v = buf[ibuf++]; tr[a].cells[b].innerHTML = - v ? unix2iso(v).replace(' ', ', ') : 'never'; + v ? unix2ui(v).replace(' ', ', ') : 'never'; } for (var a = 0; a < tr.length; a++) diff --git a/copyparty/web/splash.js b/copyparty/web/splash.js index f0c38b54..e55f7ff0 100644 --- a/copyparty/web/splash.js +++ b/copyparty/web/splash.js @@ -1,3 +1,4 @@ +// please add translations in alphabetic order, but keep "nor" and "eng" first var Ls = { "nor": { "a1": "oppdater", @@ -50,7 +51,6 @@ var Ls = { "ta2": "repeat to confirm new password:", "ta3": "found a typo; please try again", }, - "chi": { "a1": "更新", "b1": "你好   (你尚未登录)", @@ -92,7 +92,174 @@ var Ls = { "ae1": "正在下载:", //m "af1": "显示最近上传的文件", //m "ag1": "查看已知 IdP 用户", //m - } + }, + "deu": { + "a1": "Neu laden", + "b1": "Tach, wie geht's?   (Du bist nicht angemeldet)", + "c1": "Abmelden", + "d1": "Zustand", + "d2": "Zeigt den Zustand aller aktiven Threads", + "e1": "Config neu laden", + "e2": "Konfigurationsdatei neu laden (Accounts/Volumes/VolFlags)$Nund scannt alle e2ds-Volumes$N$NBeachte: Jegliche Änderung an globalen Einstellungen$Nbenötigt einen Neustart zum Anwenden", + "f1": "Du kannst lesen:", + "g1": "Du kannst hochladen nach:", + "cc1": "Andere Dinge:", + "h1": "k304 deaktivieren", + "i1": "k304 aktivieren", + "j1": "k304 trennt die Clientverbindung bei jedem HTTP 304, was Bugs mit problematischen Proxies vorbeugen kann (z.B. nicht ladenden Seiten), macht Dinge aber generell langsamer", + "k1": "Client-Einstellungen zurücksetzen", + "l1": "Melde dich an für mehr:", + "m1": "Willkommen zurück,", + "n1": "404 Nicht gefunden  ┐( ´ -`)┌", + "o1": 'or maybe you don\'t have access -- try a password or go home', + "p1": "403 Verboten  ~┻━┻", + "q1": 'Benutze ein Passwort oder gehe zur Homepage', + "r1": "Gehe zur Homepage", + ".s1": "Neu scannen", + "t1": "Aktion", + "u2": "time since the last server write$N( upload / rename / ... )$N$N17d = 17 days$N1h23 = 1 hour 23 minutes$N4m56 = 4 minutes 56 seconds", + "v1": "Verbinden", + "v2": "Benutze diesen Server als lokale Festplatte", + "w1": "Zu HTTPS wechseln", + "x1": "Passwort ändern", + "y1": "Shares bearbeiten", + "z1": "Share entsperren:", + "ta1": "Trage zuerst dein Passwort ein", + "ta2": "Wiederhole dein Passwort zur Bestätigung:", + "ta3": "Da stimmt etwas nicht; probier's nochmal", + "aa1": "Eingehende Dateien:", + "ab1": "no304 deaktivieren", + "ac1": "no304 aktivieren", + "ad1": "Das Aktivieren von no304 deaktiviert jegliche Form von Caching; probier dies, wenn k304 nicht genug war. Dies verschwendet eine grosse Menge Netzwerk-Traffic!", + "ae1": "Aktive Downloads:", + "af1": "Zeige neue Uploads", + }, + "fin": { + "a1": "päivitä", + "b1": "hei sie muukalainen   (et ole kirjautunut sisään)", + "c1": "kirjaudu ulos", + "d1": "tulosta pinojälki", + "d2": "näytä kaikkien aktiivisten säikeiden tila", + "e1": "päivitä konffit", + "e2": "lataa konfiguraatiotiedostot uudelleen (käyttäjätilit/asemat/asemaflagit),$Nja skannaa kaikki e2ds asemat uudelleen$N$Nhuom: kaikki global-asetuksiin$Ntehdyt muutokset vaativat täyden$Nuudelleenkäynnistyksen", + "f1": "voit selata:", + "g1": "voit ladata:", + "cc1": "muuta:", + "h1": "poista k304 käytöstä", + "i1": "ota k304 käyttöön", + "j1": "k304 katkaisee yhteytesi jokaisella HTTP 304:llä, mikä voi estää joitain bugisia välityspalvelimia jumittumasta/lopettamasta sivujen lataamista, mutta se myös vähentää suorituskykyä", + "k1": "nollaa asetukset", + "l1": "kirjaudu sisään:", + "m1": "tervetuloa takaisin,", + "n1": "404: ei löytynyt mitään  ┐( ´ -`)┌", + "o1": 'tai ehkä sinulla ei vain ole käyttöoikeuksia? kokeile salasanaa tai mene kotiin', + "p1": "403: pääsy kielletty  ~┻━┻", + "q1": 'kokeile salasanaa tai mene kotiin', + "r1": "mene kotiin", + ".s1": "uudelleenkartoita", + "t1": "toiminto", + "u2": "aika viimeisestä palvelimen kirjoituksesta$N( lataus / uudelleennimeäminen / tms. )$N$N17d = 17 päivää$N1h23 = 1 tunti 23 minuuttia$N4m56 = 4 minuuttia 56 sekuntia", + "v1": "yhdistä", + "v2": "käytä tätä palvelinta paikallisena kiintolevynä", + "w1": "vaihda https:ään", + "x1": "vaihda salasana", + "y1": "muokkaa jakoja", + "z1": "avaa tämä jako:", + "ta1": "täytä ensin uusi salasana", + "ta2": "toista vahvistaaksesi uuden salasanan:", + "ta3": "löytyi kirjoitusvirhe; yritä uudelleen", + "aa1": "saapuvat:", + "ab1": "poista no304 käytöstä", + "ac1": "ota no304 käyttöön", + "ad1": "no304:n lopettaa välimuistin käytön kokonaan; kokeile tätä jos k304 ei riittänyt. Tuhlaa valtavan määrän verkkoliikennettä!", + "ae1": "lähtevät:", + "af1": "näytä viimeaikaiset lataukset", + "ag1": "näytä tunnetut IdP-käyttäjät", + }, + "spa": { + "a1": "actualizar", + "b1": "hola   (no has iniciado sesión)", + "c1": "cerrar sesión", + "d1": "volcar estado de la pila", + "d2": "muestra el estado de todos los hilos activos", + "e1": "recargar configuración", + "e2": "recargar archivos de configuración (cuentas/volúmenes/indicadores de vol.),$Ny reescanear todos los volúmenes e2ds$N$Nnota: cualquier cambio en la configuración global$Nrequiere un reinicio completo para surtir efecto", + "f1": "puedes explorar:", + "g1": "puedes subir a:", + "cc1": "otras cosas:", + "h1": "desactivar k304", + "i1": "activar k304", + "j1": "activar k304 desconectará tu cliente en cada HTTP 304, lo que puede evitar que algunos proxies con errores se atasquen (dejando de cargar páginas de repente), pero también ralentizará las cosas en general", + "k1": "restablecer config. de cliente", + "l1": "inicia sesión para más:", + "m1": "bienvenido de nuevo,", + "n1": "404 no encontrado  ┐( ´ -`)┌", + "o1": '¿o quizás no tienes acceso? -- prueba con una contraseña o vuelve al inicio', + "p1": "403 prohibido  ~┻━┻", + "q1": 'usa una contraseña o vuelve al inicio', + "r1": "ir al inicio", + ".s1": "reescanear", + "t1": "acción", + "u2": "tiempo desde la última escritura en el servidor$N( subida / renombrar / ... )$N$N17d = 17 días$N1h23 = 1 hora 23 minutos$N4m56 = 4 minutos 56 segundos", + "v1": "conectar", + "v2": "usar este servidor como un disco duro local", + "w1": "cambiar a https", + "x1": "cambiar contraseña", + "y1": "editar recursos compartidos", + "z1": "desbloquear este recurso compartido:", + "ta1": "primero escribe tu nueva contraseña", + "ta2": "repite para confirmar la nueva contraseña:", + "ta3": "hay un error; por favor, inténtalo de nuevo", + "aa1": "archivos entrantes:", + "ab1": "desactivar no304", + "ac1": "activar no304", + "ad1": "activar no304 desactivará todo el almacenamiento en caché; prueba esto si k304 no fue suficiente. ¡Esto desperdiciará una gran cantidad de tráfico de red!", + "ae1": "descargas activas:", + "af1": "mostrar subidas recientes", + "ag1": "mostrar usuarios IdP conocidos" + }, + "rus": { + "a1": "обновить", + "b1": "приветик, незнакомец   (вы не авторизованы)", + "c1": "выйти", + "d1": "трассировка стека", + "d2": "показывает состояние всех активных потоков", + "e1": "перезагрузить конфиг", + "e2": "перезагрузить файлы конфига (аккаунты/хранилища/флаги),$Nи пересканировать все хранилища с флагом e2ds$N$Nвнимание: изменения глобальных настроек$Nтребуют полного перезапуска сервера", + "f1": "вы можете видеть:", + "g1": "вы можете загружать файлы в:", + "cc1": "всякая всячина:", + "h1": "отключить k304", + "i1": "включить k304", + "j1": "включённый k304 будет отключать вас при получении HTTP 304, что может помочь при работе с некоторыми глючными прокси (перестают загружаться страницы), но это также сделает работу клиента медленнее", + "k1": "сбросить локальные настройки", + "l1": "авторизуйтесь для других опций:", + "m1": "с возвращением,", + "n1": "404 не найдено  ┐( ´ -`)┌", + "o1": 'или у вас нет доступа -- попробуйте авторизоваться или вернуться на главную', + "p1": "403 доступ запрещён  ~┻━┻", + "q1": 'авторизуйтесь или вернитесь на главную', + "r1": "вернуться на главную", + ".s1": "пересканировать", + "t1": "действия", + "u2": "время с последней записи на сервер$N( загрузка / переименование / ... )$N$N17d = 17 дней$N1h23 = 1 час 23 минут$N4m56 = 4 минут 56 секунд", + "v1": "подключить", + "v2": "использовать сервер как локальный диск", + "w1": "перейти на https", + "x1": "поменять пароль", + "y1": "управление доступом", + "z1": "разблокировать:", + "ta1": "сначала введите свой новый пароль", + "ta2": "повторите новый пароль:", + "ta3": "опечатка; попробуйте снова", + "aa1": "входящие файлы:", + "ab1": "отключить no304", + "ac1": "включить no304", + "ad1": "включённый no304 полностью отключит хеширование; используйте, если k304 не помог. Сильно увеличит объём трафика!", + "ae1": "активные скачивания:", + "af1": "показать недавние загрузки", + "ag1": "показать известных IdP-пользователей", + }, }; if (window.langmod) diff --git a/copyparty/web/svcs.html b/copyparty/web/svcs.html index c47d8403..a4b57746 100644 --- a/copyparty/web/svcs.html +++ b/copyparty/web/svcs.html @@ -240,14 +240,26 @@

ShareX

-

to upload screenshots using ShareX v12 or v15+, save this as copyparty.sxcu and run it:

+

to upload screenshots using ShareX v15+, save this as copyparty.sxcu and run it:

+ +
+                { "Version": "15.0.0", "Name": "copyparty",
+                "RequestURL": "http{{ s }}://{{ ep }}/{{ rvp }}",
+                "Headers": {
+                    {% if accs %}"pw": "{{ pw }}", {% endif %}"accept": "url"
+                },
+                "DestinationType": "ImageUploader, TextUploader, FileUploader",
+                "Body": "MultipartFormData", "URL": "{response}",
+                "RequestMethod": "POST", "FileFormName": "f" }
+            
+ +

for ShareX v12 specifically, save this as copyparty.sxcu and run it:

                 { "Name": "copyparty",
                 "RequestURL": "http{{ s }}://{{ ep }}/{{ rvp }}",
                 "Headers": {
-                    {% if accs %}"pw": "{{ pw }}",{% endif %}
-                    "accept": "url"
+                    {% if accs %}"pw": "{{ pw }}", {% endif %}"accept": "url"
                 },
                 "DestinationType": "ImageUploader, TextUploader, FileUploader",
                 "FileFormName": "f" }
diff --git a/copyparty/web/up2k.js b/copyparty/web/up2k.js
index edf0eee8..2f588446 100644
--- a/copyparty/web/up2k.js
+++ b/copyparty/web/up2k.js
@@ -2511,8 +2511,8 @@ function up2k_init(subtle) {
                         var msg = [];
                         for (var a = 0, aa = Math.min(20, response.hits.length); a < aa; a++) {
                             var hit = response.hits[a],
-                                tr = unix2iso(hit.ts),
-                                tu = unix2iso(t.lmod),
+                                tr = unix2ui(hit.ts),
+                                tu = unix2ui(t.lmod),
                                 diff = parseInt(t.lmod) - parseInt(hit.ts),
                                 cdiff = (Math.abs(diff) <= 2) ? '3c0' : 'f0b',
                                 sdiff = 'diff ' + diff;
@@ -3187,7 +3187,7 @@ function up2k_init(subtle) {
             return;
 
         try {
-            ebi('lifew').innerHTML = unix2iso((st.lifetime || lifetime) +
+            ebi('lifew').innerHTML = unix2ui((st.lifetime || lifetime) +
                 Date.now() / 1000 - new Date().getTimezoneOffset() * 60
             ).replace(' ', ', ').slice(0, -3);
         }
diff --git a/copyparty/web/util.js b/copyparty/web/util.js
index b246e145..94f73f24 100644
--- a/copyparty/web/util.js
+++ b/copyparty/web/util.js
@@ -907,11 +907,29 @@ function noq_href(el) {
 }
 
 
+function pad2(v) {
+    return ('0' + v).slice(-2);
+}
+
+
 function unix2iso(ts) {
     return new Date(ts * 1000).toISOString().replace("T", " ").slice(0, -5);
 }
 
 
+function unix2iso_localtime(ts) {
+    var o = new Date(ts * 1000),
+        p = pad2;
+    return "{0}-{1}-{2} {3}:{4}:{5}".format(
+        o.getFullYear(),
+        p(o.getMonth() + 1),
+        p(o.getDate()),
+        p(o.getHours()),
+        p(o.getMinutes()),
+        p(o.getSeconds()));
+}
+
+
 function s2ms(s) {
     s = Math.floor(s);
     var m = Math.floor(s / 60);
@@ -1203,6 +1221,13 @@ function scfg_bind(obj, oname, cname, defval, cb) {
 }
 
 
+window.unix2ui = (function () {
+    var v = sread('utctid');
+    v = v ? (v === '0') : (window.dutc === false);
+    return v ? unix2iso_localtime : unix2iso;
+})();
+
+
 function hist_push(url) {
     console.log("h-push " + url);
     try {
diff --git a/docs/changelog.md b/docs/changelog.md
index 7a9571f1..5e1d7717 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -1,3 +1,81 @@
+▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀  
+# 2025-0731-0833  `v1.18.8`  sfx hotfix
+
+## 🩹 bugfixes
+
+* #354 fix `copyparty-sfx.py` failing to start on certain versions of python c17ce4892ecdb4e11437bc2785d132bd8100eaec
+
+
+
+▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀  
+# 2025-0730-2131  `v1.18.7`  SECURITY: fix another XSS
+
+## ⚠️ ATTN: this release fixes an XSS vulnerability
+
+[GHSA-8mx2-rjh8-q3jq](https://github.com/9001/copyparty/security/advisories/GHSA-8mx2-rjh8-q3jq), could let an attacker execute arbitrary JS by tricking you into clicking a malicious URL
+
+Soon there won't be many of these left, surely. Huge thanks to @Ju0x for finding and reporting this.
+
+## 🧪 new features
+
+* #265 uid/gid for new files can be configured per-volume f1959988
+  * has preconditions; [see readme](https://github.com/9001/copyparty#chmod-and-chown)
+* #212 add German translation (thx @rGunti, @Scotsguy, @chocolateimage) 9d32564c
+
+## 🩹 bugfixes
+
+* GHSA-8mx2-rjh8-q3jq a8705e61
+* #276 windows: fix segfault (thx @kernel1994 for debugging!) a9d07c63
+* #272 webdav: send disk-size and disk-free to clients 4988a55e
+* #285 use disk-free sans root-reserve on linux (thx @Arklaum!) c3cc2dde 
+* cors-check was funky on IPv6 e9684d40
+* #325 upgrade sharex example for newer versions 6016ec93
+* #300 restore support for old versions of python 2.7 b7ca6f4a
+
+## 🔧 other changes
+
+* shares: the config POST-target is now always the webroot (for ease of IdP configuration) fb7cbc42 
+* unlist: now applies to the navpane too fbf17be2
+* windows: show disk-usage as well, not just disk-free 5c6341e9
+* #228 nix-pkg improvements (thx @dtomvan!) 4915b14b
+* docker-compose: ensure logs appear in realtime 3cde1f3b
+* mention that IdP-volumes and users [can now be persisted](https://github.com/9001/copyparty/blob/hovudstraum/docs/idp.md#but-you-can-enable-idp-volume-persistence) 6069bc9b
+* #316 explain a scary-looking thing in the code 053de619
+
+
+
+▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀  
+# 2025-0728-2320  `v1.18.6`  reflink-dedup
+
+## 🧪 new features
+
+* #201 add support for reflink-based dedup on cow filesystems df9feabc
+  * combine `--dedup` with `--reflink` to enable, or volflags with same name
+  * a better and safer alternative to the other dedup approaches (symlink/hardlink), but only possible to use in some cases:
+    * needs linux 5.3 or newer, python 3.14 or newer, btrfs/xfs/zfs
+    * not available in the docker images yet; needs a new version of python, so maybe next alpine release (november/december 2025)
+* ratelimit password changes to impede bruteforcing a2601fd6
+  * limit is set by `--ban-pwc` (default is 5 changes in 60min)
+
+## 🩹 bugfixes
+
+* #240 nixos: fix unixgroups issue (thx @chinponya!) 7c9c962b
+* #246 cbz: use correct page for thumbnail (thx @Scotsguy!) 542a1de1
+
+## 🔧 other changes
+
+* volflag `nosub` now also prevents mkdir 0f2c6235
+* improve documentation:
+  * #229 use the same example UDS path everywhere cb019afe
+  * [example nginx config](https://github.com/9001/copyparty/blob/hovudstraum/contrib/nginx/copyparty.conf) had misleading cloudflare comment (thx @jmi2k!) 674fc1fe
+  * more readable `--help-chmod` 03d23dae
+  * #244 fix typo in `--help` 4f013f64
+* #242 hide "use real pw" on connectpage if no accounts (thx @toast003!) 025942a7
+* #211 docker: remove deprecated attribute (thx @ptweezy!) 5b98e104
+* #190 add the feature-showcase video to the readme (thx @RustoMCSpit!) 43e6da34
+
+
+
 ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀  
 # 2025-0727-2305  `v1.18.5`  SECURITY: fix XSS in media tags
 
diff --git a/docs/devnotes.md b/docs/devnotes.md
index 3db6b201..229cb398 100644
--- a/docs/devnotes.md
+++ b/docs/devnotes.md
@@ -415,6 +415,8 @@ to get started, first `cd` into the `scripts` folder
 
 * if you want to build the `.pyz` standalone "binary", now run `./make-pyz.sh`
 
+* if you want to build the `tar.gz` for use in a linux-distro package, now run `./make-tgz-release.sh theVersionNumber`
+
 * if you want to build a pypi package, now run `./make-pypi-release.sh d`
 
 * if you want to build a docker-image, you have two options:
diff --git a/docs/idp.md b/docs/idp.md
index f3dc7e8c..c27a9355 100644
--- a/docs/idp.md
+++ b/docs/idp.md
@@ -9,9 +9,9 @@ in the copyparty `[global]` config, specify which headers to read client info fr
 
 # important notes
 
-## IdP volumes are forgotten on shutdown
+## by default, IdP volumes are forgotten on shutdown
 
-IdP volumes, meaning dynamically-created volumes, meaning volumes that contain `${u}` or `${g}` in their URL, will be forgotten during a server restart and then "revived" when the volume's owner sends their first request after the restart
+IdP volumes, meaning dynamically-created volumes, meaning volumes that contain `${u}` or `${g}` in their URL, will (by default) be forgotten during a server restart and then "revived" when the volume's owner sends their first request after the restart
 
 until each IdP volume is revived, it will inherit the permissions of its parent volume (if any)
 
@@ -19,7 +19,17 @@ this means that, if an IdP volume is located inside a folder that is readable by
 
 and likewise -- if the IdP volume is inside a folder that is only accessible by certain users, but the IdP volume is configured to allow access from unauthenticated users, then the contents of the volume will NOT be accessible until it is revived
 
-until this limitation is fixed (if ever), it is recommended to place IdP volumes inside an appropriate parent volume, so they can inherit acceptable permissions until their revival; see the "strategic volumes" at the bottom of [./examples/docker/idp/copyparty.conf](./examples/docker/idp/copyparty.conf)
+it is recommended to place IdP volumes inside an appropriate parent volume, so they can inherit acceptable permissions until their revival; see the "strategic volumes" at the bottom of [./examples/docker/idp/copyparty.conf](./examples/docker/idp/copyparty.conf)
+
+## but you can enable IdP volume persistence
+
+global-option `idp-store` can enable user/group persistence across restarts;
+
+* `idp-store: 1` (default) will log users into a database, but not actually "remember" them (the knowledge is ignored)
+* `idp-store: 2` remembers usernames only
+* `idp-store: 3` remembers usernames and their groups
+
+the reason why this is default-disabled, is because you may expect copyparty to forget about a user when you delete them from the IdP-server; this will not be the case any longer, you will need to click `view idp cache` in the controlpanel and manually remove the users you want gone
 
 
 ## Connecting webdav clients
diff --git a/scripts/prep.sh b/scripts/prep.sh
index 791d8eec..c08d09ed 100755
--- a/scripts/prep.sh
+++ b/scripts/prep.sh
@@ -22,10 +22,31 @@ update_arch_pkgbuild() {
     rm -rf x
 }
 
+update_mpr_pkgbuild() {
+    cd "$self/../contrib/package/makedeb-mpr"
+    rm -rf x
+    mkdir x
+
+    sha=$(sha256sum "$self/../dist/copyparty-$ver.tar.gz" | awk '{print$1}')
+
+    # awk -v ver=$ver -v sha=$sha '
+    #     /^pkgver=/{sub(/[0-9\.]+/,ver)};
+    #     /^sha256sums=/{sub(/[0-9a-f]{64}/,sha)};
+    #     1' PKGBUILD >a
+    # mv a PKGBUILD
+
+		echo thing 1
+		sed -s -i "s/pkgver=\"\"/pkgver=\"$ver\"/" PKGBUILD
+		sed -s -i "s/sha256sums=(\".*\")/sha256sums=(\"$sha\")/" PKGBUILD
+
+    rm -rf x
+}
+
 update_nixos_pin() {
     ( cd $self/../contrib/package/nix/copyparty;
       ./update.py $self/../dist/copyparty-sfx.py )
 }
 
 update_arch_pkgbuild
+update_mpr_pkgbuild
 update_nixos_pin
diff --git a/scripts/pyinstaller/build.sh b/scripts/pyinstaller/build.sh
index bb1d477e..a444ff94 100644
--- a/scripts/pyinstaller/build.sh
+++ b/scripts/pyinstaller/build.sh
@@ -14,7 +14,6 @@ clean=--clean
 
 uname -s | grep WOW64 && m=64 || m=32
 uname -s | grep NT-10 && w10=1 || w7=1
-[ $w7 ] && export PRTY_NO_MAGIC=1
 [ $w7 ] && [ -e up2k.sh ] && [ ! "$1" ] && ./up2k.sh
 
 [ $w7 ] && pyv=37 || pyv=313
diff --git a/tests/util.py b/tests/util.py
index 17c1d06d..42a47907 100644
--- a/tests/util.py
+++ b/tests/util.py
@@ -143,7 +143,7 @@ class Cfg(Namespace):
     def __init__(self, a=None, v=None, c=None, **ka0):
         ka = {}
 
-        ex = "chpw cookie_lax daw dav_auth dav_mac dav_rt e2d e2ds e2dsa e2t e2ts e2tsr e2v e2vu e2vp early_ban ed emp exp force_js getmod grid gsel hardlink hardlink_only ih ihead magic nid nih no_acode no_athumb no_bauth no_clone no_cp no_dav no_db_ip no_del no_dirsz no_dupe no_lifetime no_logues no_mv no_pipe no_poll no_readme no_robots no_sb_md no_sb_lg no_scandir no_tail no_tarcmp no_thumb no_vthumb no_zip nrand nsort nw og og_no_head og_s_title ohead q rand re_dirsz reflink rmagic rss smb srch_dbg srch_excl stats uqe vague_403 vc ver wo_up_readme write_uplog xdev xlink xvol zipmaxu zs"
+        ex = "chpw cookie_lax daw dav_auth dav_mac dav_rt e2d e2ds e2dsa e2t e2ts e2tsr e2v e2vu e2vp early_ban ed emp exp force_js getmod grid gsel hardlink hardlink_only ih ihead localtime magic nid nih no_acode no_athumb no_bauth no_clone no_cp no_dav no_db_ip no_del no_dirsz no_dupe no_lifetime no_logues no_mv no_pipe no_poll no_readme no_robots no_sb_md no_sb_lg no_scandir no_tail no_tarcmp no_thumb no_vthumb no_zip nrand nsort nw og og_no_head og_s_title ohead q rand re_dirsz reflink rmagic rss smb srch_dbg srch_excl stats uqe vague_403 vc ver wo_up_readme write_uplog xdev xlink xvol zipmaxu zs"
         ka.update(**{k: False for k in ex.split()})
 
         ex = "dav_inf dedup dotpart dotsrch hook_v no_dhash no_fastboot no_fpool no_htp no_rescan no_sendfile no_ses no_snap no_up_list no_voldump re_dhash see_dots plain_ip"
@@ -152,6 +152,9 @@ class Cfg(Namespace):
         ex = "ah_cli ah_gen css_browser dbpath hist ipu js_browser js_other mime mimes no_forget no_hash no_idx nonsus_urls og_tpl og_ua ua_nodoc ua_nozip"
         ka.update(**{k: None for k in ex.split()})
 
+        ex = "gid uid"
+        ka.update(**{k: -1 for k in ex.split()})
+
         ex = "hash_mt hsortn qdel safe_dedup srch_time tail_fd tail_rate u2abort u2j u2sz"
         ka.update(**{k: 1 for k in ex.split()})
 
timesizedonefile
' + (done ? L.un_del : L.un_abrt) + '' + unix2iso(res[a].at) + '' + unix2ui(res[a].at) + '' + ('' + res[a].sz).replace(/\B(?=(\d{3})+(?!\d))/g, " ") + '100%' + res[a].pd + '%' + linksplit(res[a].vp).join(' / ') + '