// Copyright (C) 2026 Danilo M. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. .pragma library // The file state's Do row. op is a fileops operation, or "md" for the // daemon's write, or "compress", which opens the COMPRESS formats. kinds // lists the staged kinds it fits ("any" fits every mix); min is the number // of files it needs and max the most it takes (To .md writes one file from // one PDF); format is the suffix a file already has when the // operation would not change it. icon is a Nerd Font codepoint, checked in // Inconsolata Nerd Font's cmap. const OPS = [ { label: "To .md", icon: "\uf48a", op: "md", kinds: ["pdf"], max: 1 }, { label: "To images", icon: "\uf1c5", op: "pdf-images", kinds: ["pdf"] }, { label: "Merge", icon: "\uf419", op: "pdf-merge", kinds: ["pdf"], min: 2 }, { label: "Extract audio", icon: "\uf001", op: "audio", kinds: ["video"] }, { label: "To MP4", icon: "\uf008", op: "mp4", kinds: ["video"], format: [".mp4"] }, { label: "To WebM", icon: "\uf008", op: "webm", kinds: ["video"], format: [".webm"] }, { label: "To GIF", icon: "\uf1c8", op: "gif", kinds: ["video"] }, { label: "Trackcrop", icon: "\uf05b", op: "trackcrop", kinds: ["video"] }, { label: "To PNG", icon: "\uf03e", op: "png", kinds: ["image"], format: [".png"] }, { label: "To JPEG", icon: "\uf03e", op: "jpeg", kinds: ["image"], format: [".jpg", ".jpeg"] }, { label: "To WebP", icon: "\uf03e", op: "webp", kinds: ["image"], format: [".webp"] }, { label: "Resize 50%", icon: "\uf065", op: "half", kinds: ["image"] }, { label: "Extract", icon: "\uf07c", op: "extract", kinds: ["archive"] }, { label: "Compress…", icon: "\uf1c6", op: "compress", kinds: ["any"] }, ]; var COMPRESS = [ { label: ".zip", icon: "\uf1c6", op: "zip" }, { label: ".tar.gz", icon: "\uf1c6", op: "tgz" }, { label: ".tar.xz", icon: "\uf1c6", op: "txz" }, { label: ".tar.bz2", icon: "\uf1c6", op: "tbz2" }, ]; function ext(name) { const n = name.toLowerCase(), dot = n.lastIndexOf("."); return dot > 0 ? n.slice(dot) : ""; } function offered(files) { if (!files.length) return []; return OPS.filter(o => (o.kinds.includes("any") || files.every(f => o.kinds.includes(f.kind))) && files.length >= (o.min ?? 1) && files.length <= (o.max ?? Infinity) && !(o.format && files.every(f => o.format.includes(ext(f.name))))); }