|
@@ -0,0 +1,2541 @@
|
|
|
|
|
+/*
|
|
|
|
|
+THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
|
|
|
|
+if you want to view the source, please visit the github repository of this plugin
|
|
|
|
|
+*/
|
|
|
|
|
+
|
|
|
|
|
+var __defProp = Object.defineProperty;
|
|
|
|
|
+var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
|
|
+var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
|
|
|
+var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
|
|
|
+var __export = (target, all) => {
|
|
|
|
|
+ for (var name in all)
|
|
|
|
|
+ __defProp(target, name, { get: all[name], enumerable: true });
|
|
|
|
|
+};
|
|
|
|
|
+var __copyProps = (to, from, except, desc) => {
|
|
|
|
|
+ if (from && typeof from === "object" || typeof from === "function") {
|
|
|
|
|
+ for (let key of __getOwnPropNames(from))
|
|
|
|
|
+ if (!__hasOwnProp.call(to, key) && key !== except)
|
|
|
|
|
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
|
|
|
+ }
|
|
|
|
|
+ return to;
|
|
|
|
|
+};
|
|
|
|
|
+var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
|
|
|
+
|
|
|
|
|
+// src/main.ts
|
|
|
|
|
+var main_exports = {};
|
|
|
|
|
+__export(main_exports, {
|
|
|
|
|
+ default: () => AttachmentManagementPlugin
|
|
|
|
|
+});
|
|
|
|
|
+module.exports = __toCommonJS(main_exports);
|
|
|
|
|
+var import_obsidian12 = require("obsidian");
|
|
|
|
|
+
|
|
|
|
|
+// src/settings/settings.ts
|
|
|
|
|
+var import_obsidian4 = require("obsidian");
|
|
|
|
|
+
|
|
|
|
|
+// src/lib/constant.ts
|
|
|
|
|
+var SETTINGS_VARIABLES_DATES = "${date}";
|
|
|
|
|
+var SETTINGS_VARIABLES_NOTEPATH = "${notepath}";
|
|
|
|
|
+var SETTINGS_VARIABLES_NOTENAME = "${notename}";
|
|
|
|
|
+var SETTINGS_VARIABLES_NOTEPARENT = "${parent}";
|
|
|
|
|
+var SETTINGS_VARIABLES_ORIGINALNAME = "${originalname}";
|
|
|
|
|
+var SETTINGS_VARIABLES_MD5 = "${md5}";
|
|
|
|
|
+var SETTINGS_ROOT_OBSFOLDER = "obsFolder";
|
|
|
|
|
+var SETTINGS_ROOT_INFOLDER = "inFolderBelow";
|
|
|
|
|
+var SETTINGS_ROOT_NEXTTONOTE = "nextToNote";
|
|
|
|
|
+
|
|
|
|
|
+// src/model/extensionOverride.ts
|
|
|
|
|
+var import_obsidian3 = require("obsidian");
|
|
|
|
|
+
|
|
|
|
|
+// src/utils.ts
|
|
|
|
|
+var import_obsidian2 = require("obsidian");
|
|
|
|
|
+
|
|
|
|
|
+// src/i18n/index.ts
|
|
|
|
|
+var import_obsidian = require("obsidian");
|
|
|
|
|
+
|
|
|
|
|
+// src/i18n/locales/ja.ts
|
|
|
|
|
+var ja = {
|
|
|
|
|
+ common: {
|
|
|
|
|
+ cancel: "\u30AD\u30E3\u30F3\u30BB\u30EB"
|
|
|
|
|
+ },
|
|
|
|
|
+ settings: {
|
|
|
|
|
+ title: "Attachment Management \u8A2D\u5B9A",
|
|
|
|
|
+ rootPath: {
|
|
|
|
|
+ name: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u4FDD\u5B58\u5148\u30EB\u30FC\u30C8\u30D1\u30B9",
|
|
|
|
|
+ desc: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30EB\u30FC\u30C8\u30D1\u30B9\u3092\u9078\u629E",
|
|
|
|
|
+ options: {
|
|
|
|
|
+ obsidian: "Obsidian \u306E\u8A2D\u5B9A\u3092\u30B3\u30D4\u30FC",
|
|
|
|
|
+ inFolder: "\u6307\u5B9A\u3057\u305F\u30D5\u30A9\u30EB\u30C0\u5185",
|
|
|
|
|
+ nextToNote: "\u30CE\u30FC\u30C8\u3068\u540C\u3058\u30D5\u30A9\u30EB\u30C0\u5185\u306E\u6307\u5B9A\u3057\u305F\u30B5\u30D6\u30D5\u30A9\u30EB\u30C0"
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ rootFolder: {
|
|
|
|
|
+ name: "\u30EB\u30FC\u30C8\u30D5\u30A9\u30EB\u30C0",
|
|
|
|
|
+ desc: "\u65B0\u3057\u3044\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30EB\u30FC\u30C8\u30D5\u30A9\u30EB\u30C0"
|
|
|
|
|
+ },
|
|
|
|
|
+ attachmentPath: {
|
|
|
|
|
+ name: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D1\u30B9",
|
|
|
|
|
+ desc: "\u30EB\u30FC\u30C8\u30D5\u30A9\u30EB\u30C0\u5185\u306E\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D1\u30B9\u3002\u5229\u7528\u53EF\u80FD\u306A\u5909\u6570\uFF1A${notepath}\u3001${notename}\u3001${parent}"
|
|
|
|
|
+ },
|
|
|
|
|
+ attachmentFormat: {
|
|
|
|
|
+ name: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8",
|
|
|
|
|
+ desc: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u540D\u524D\u306E\u4ED8\u3051\u65B9\u3092\u5B9A\u7FA9\u3057\u307E\u3059\u3002\u5229\u7528\u53EF\u80FD\u306A\u5909\u6570\uFF1A${date}\u3001${notename}\u3001${md5}\u3001${originalname}\u3002"
|
|
|
|
|
+ },
|
|
|
|
|
+ dateFormat: {
|
|
|
|
|
+ name: "\u65E5\u4ED8\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8",
|
|
|
|
|
+ desc: "\u4F7F\u7528\u3059\u308B Moment.js \u306E\u65E5\u4ED8\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8",
|
|
|
|
|
+ linkText: "Moment.js \u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u30AA\u30D7\u30B7\u30E7\u30F3"
|
|
|
|
|
+ },
|
|
|
|
|
+ autoRename: {
|
|
|
|
|
+ name: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u3092\u81EA\u52D5\u3067\u30EA\u30CD\u30FC\u30E0",
|
|
|
|
|
+ desc: "\u5BFE\u5FDC\u3059\u308B md/canvas \u30D5\u30A1\u30A4\u30EB\u304C\u7F6E\u304B\u308C\u3066\u3044\u308B\u30D5\u30A9\u30EB\u30C0/\u30D5\u30A1\u30A4\u30EB\u306E\u540D\u524D\u3092\u5909\u66F4\u3059\u308B\u3068\u3001\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D5\u30A9\u30EB\u30C0/\u30D5\u30A1\u30A4\u30EB\u540D\u3082\u81EA\u52D5\u7684\u306B\u5909\u66F4\u3055\u308C\u307E\u3059\u3002"
|
|
|
|
|
+ },
|
|
|
|
|
+ extensionOverride: {
|
|
|
|
|
+ name: "\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A",
|
|
|
|
|
+ desc: "\u7279\u5B9A\u306E\u62E1\u5F35\u5B50\uFF08\u4F8B\uFF1Apdf \u3084 zip\uFF09\u3092\u6301\u3064\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u3092\u81EA\u52D5\u30EA\u30CD\u30FC\u30E0\u3057\u305F\u3044\u5834\u5408\u3001\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002",
|
|
|
|
|
+ addButton: "\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u3092\u8FFD\u52A0",
|
|
|
|
|
+ extension: {
|
|
|
|
|
+ name: "\u62E1\u5F35\u5B50",
|
|
|
|
|
+ desc: "\u4E0A\u66F8\u304D\u3059\u308B\u62E1\u5F35\u5B50",
|
|
|
|
|
+ placeholder: "pdf|docx?"
|
|
|
|
|
+ },
|
|
|
|
|
+ tooltips: {
|
|
|
|
|
+ remove: "\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u3092\u524A\u9664",
|
|
|
|
|
+ edit: "\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u3092\u7DE8\u96C6",
|
|
|
|
|
+ save: "\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u3092\u4FDD\u5B58"
|
|
|
|
|
+ },
|
|
|
|
|
+ saveNotice: "\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u3092\u4FDD\u5B58\u3057\u307E\u3057\u305F"
|
|
|
|
|
+ },
|
|
|
|
|
+ excludeExtension: {
|
|
|
|
|
+ name: "\u9664\u5916\u3059\u308B\u62E1\u5F35\u5B50\u306E\u30D1\u30BF\u30FC\u30F3",
|
|
|
|
|
+ desc: "\u51E6\u7406\u5BFE\u8C61\u304B\u3089\u9664\u5916\u3059\u308B\u62E1\u5F35\u5B50\u3092\u6B63\u898F\u8868\u73FE\u3067\u6307\u5B9A\u3057\u307E\u3059\u3002",
|
|
|
|
|
+ placeholder: "pdf|docx?|xlsx?|pptx?|zip|rar"
|
|
|
|
|
+ },
|
|
|
|
|
+ excludedPaths: {
|
|
|
|
|
+ name: "\u9664\u5916\u30D1\u30B9",
|
|
|
|
|
+ desc: "\u30EA\u30CD\u30FC\u30E0\u304B\u3089\u9664\u5916\u3059\u308B\u30D5\u30A9\u30EB\u30C0\u306E\u30D5\u30EB\u30D1\u30B9\u3092\u30BB\u30DF\u30B3\u30ED\u30F3\uFF08;\uFF09\u3067\u533A\u5207\u3063\u3066\u6307\u5B9A\u3057\u307E\u3059\uFF08\u5927\u6587\u5B57\u3068\u5C0F\u6587\u5B57\u3092\u533A\u5225\u3057\u3001\u5148\u982D\u306B\u30B9\u30E9\u30C3\u30B7\u30E5\u300C/\u300D\u3092\u4ED8\u3051\u306A\u3044\u3067\u304F\u3060\u3055\u3044\uFF09\u3002"
|
|
|
|
|
+ },
|
|
|
|
|
+ excludeSubpaths: {
|
|
|
|
|
+ name: "\u30B5\u30D6\u30D1\u30B9\u3092\u9664\u5916",
|
|
|
|
|
+ desc: "\u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u30AA\u30F3\u306B\u3059\u308B\u3068\u3001\u4E0A\u8A18\u3067\u6307\u5B9A\u3057\u305F\u30D5\u30A9\u30EB\u30C0\u30D1\u30B9\u306E\u3059\u3079\u3066\u306E\u30B5\u30D6\u30D5\u30A9\u30EB\u30C0\u3082\u9664\u5916\u3055\u308C\u307E\u3059\u3002"
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ override: {
|
|
|
|
|
+ title: "\u4E0A\u66F8\u304D\u8A2D\u5B9A",
|
|
|
|
|
+ menuTitle: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u8A2D\u5B9A\u3092\u4E0A\u66F8\u304D",
|
|
|
|
|
+ addExtensionOverrides: "\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u3092\u8FFD\u52A0",
|
|
|
|
|
+ extension: {
|
|
|
|
|
+ name: "\u62E1\u5F35\u5B50",
|
|
|
|
|
+ desc: "\u4E0A\u66F8\u304D\u3059\u308B\u62E1\u5F35\u5B50",
|
|
|
|
|
+ placeholder: "pdf"
|
|
|
|
|
+ },
|
|
|
|
|
+ buttons: {
|
|
|
|
|
+ reset: "\u30EA\u30BB\u30C3\u30C8",
|
|
|
|
|
+ submit: "\u9001\u4FE1"
|
|
|
|
|
+ },
|
|
|
|
|
+ notifications: {
|
|
|
|
|
+ reset: "{path} \u306E\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u8A2D\u5B9A\u3092\u30EA\u30BB\u30C3\u30C8\u3057\u307E\u3057\u305F",
|
|
|
|
|
+ overridden: "{path} \u306E\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u8A2D\u5B9A\u3092\u4E0A\u66F8\u304D\u3057\u307E\u3057\u305F"
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ extensionOverride: {
|
|
|
|
|
+ title: "\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A",
|
|
|
|
|
+ rootPath: {
|
|
|
|
|
+ name: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u4FDD\u5B58\u5148\u30EB\u30FC\u30C8\u30D1\u30B9",
|
|
|
|
|
+ desc: "\u3053\u306E\u62E1\u5F35\u5B50\u306E\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30EB\u30FC\u30C8\u30D1\u30B9\u3092\u9078\u629E"
|
|
|
|
|
+ },
|
|
|
|
|
+ rootFolder: {
|
|
|
|
|
+ name: "\u30EB\u30FC\u30C8\u30D5\u30A9\u30EB\u30C0",
|
|
|
|
|
+ desc: "\u3053\u306E\u62E1\u5F35\u5B50\u306E\u30EB\u30FC\u30C8\u30D5\u30A9\u30EB\u30C0"
|
|
|
|
|
+ },
|
|
|
|
|
+ attachmentPath: {
|
|
|
|
|
+ name: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D1\u30B9",
|
|
|
|
|
+ desc: "\u3053\u306E\u62E1\u5F35\u5B50\u306E\u30EB\u30FC\u30C8\u30D5\u30A9\u30EB\u30C0\u5185\u306E\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D1\u30B9"
|
|
|
|
|
+ },
|
|
|
|
|
+ attachmentFormat: {
|
|
|
|
|
+ name: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8",
|
|
|
|
|
+ desc: "\u3053\u306E\u62E1\u5F35\u5B50\u306E\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u540D\u524D\u306E\u4ED8\u3051\u65B9\u3092\u5B9A\u7FA9\u3057\u307E\u3059"
|
|
|
|
|
+ },
|
|
|
|
|
+ buttons: {
|
|
|
|
|
+ save: "\u4FDD\u5B58"
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ confirm: {
|
|
|
|
|
+ title: "\u30D2\u30F3\u30C8",
|
|
|
|
|
+ message: "\u3053\u306E\u64CD\u4F5C\u306F\u5143\u306B\u623B\u305B\u305A\u3001\u5B9F\u9A13\u7684\u306A\u3082\u306E\u3067\u3059\u3002\u6700\u521D\u306B Vault \u3092\u30D0\u30C3\u30AF\u30A2\u30C3\u30D7\u3057\u3066\u304F\u3060\u3055\u3044\uFF01\u672C\u5F53\u306B\u7D9A\u884C\u3057\u307E\u3059\u304B\uFF1F",
|
|
|
|
|
+ continue: "\u7D9A\u884C"
|
|
|
|
|
+ },
|
|
|
|
|
+ notices: {
|
|
|
|
|
+ fileExcluded: "{path} \u306F\u9664\u5916\u3055\u308C\u307E\u3057\u305F",
|
|
|
|
|
+ overrideRemoved: "{path} \u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u3092\u524A\u9664\u3057\u307E\u3057\u305F",
|
|
|
|
|
+ fileRenamed: "{from} \u304B\u3089 {to} \u306B\u30EA\u30CD\u30FC\u30E0\u3057\u307E\u3057\u305F",
|
|
|
|
|
+ filesRenamedBatch: "{count} \u4EF6\u306E\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u3092\u30EA\u30CD\u30FC\u30E0\u3057\u307E\u3057\u305F",
|
|
|
|
|
+ arrangeCompleted: "\u6574\u7406\u304C\u5B8C\u4E86\u3057\u307E\u3057\u305F",
|
|
|
|
|
+ resetAttachmentSetting: "{path} \u306E\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u8A2D\u5B9A\u3092\u30EA\u30BB\u30C3\u30C8\u3057\u307E\u3057\u305F",
|
|
|
|
|
+ error: {
|
|
|
|
|
+ unknownError: "\u4E0D\u660E\u306A\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F"
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ commands: {
|
|
|
|
|
+ rearrangeAllLinks: "\u30EA\u30F3\u30AF\u3055\u308C\u3066\u3044\u308B\u3059\u3079\u3066\u306E\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u3092\u518D\u6574\u7406",
|
|
|
|
|
+ rearrangeActiveLinks: "\u30EA\u30F3\u30AF\u3055\u308C\u3066\u3044\u308B\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u3092\u518D\u6574\u7406",
|
|
|
|
|
+ resetOverrideSetting: "\u4E0A\u66F8\u304D\u8A2D\u5B9A\u3092\u30EA\u30BB\u30C3\u30C8",
|
|
|
|
|
+ clearUnusedStorage: "\u672A\u4F7F\u7528\u306E\u5143\u306E\u30D5\u30A1\u30A4\u30EB\u540D\u30B9\u30C8\u30EC\u30FC\u30B8\u3092\u30AF\u30EA\u30A2"
|
|
|
|
|
+ },
|
|
|
|
|
+ errors: {
|
|
|
|
|
+ canvasNotSupported: "Canvas \u306F\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u3068\u3057\u3066\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002",
|
|
|
|
|
+ markdownNotSupported: "Markdown \u306F\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u3068\u3057\u3066\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002",
|
|
|
|
|
+ extensionEmpty: "\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u306F\u7A7A\u306B\u3067\u304D\u307E\u305B\u3093\u3002",
|
|
|
|
|
+ duplicateExtension: "\u91CD\u8907\u3057\u305F\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u3002",
|
|
|
|
|
+ excludedExtension: "\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u306F\u3001\u9664\u5916\u3055\u308C\u305F\u62E1\u5F35\u5B50\u306B\u3067\u304D\u307E\u305B\u3093\u3002",
|
|
|
|
|
+ attachFormatEmpty: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u3092\u7A7A\u306B\u3067\u304D\u307E\u305B\u3093\u3002",
|
|
|
|
|
+ attachFormatIllegalChar: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u306B\u4E0D\u6B63\u306A\u30D5\u30A1\u30A4\u30EB\u540D\u6587\u5B57\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059\uFF1A{char}",
|
|
|
|
|
+ attachFormatUnknownVariable: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u5185\u306E\u672A\u77E5\u306E\u5909\u6570\uFF1A{name}",
|
|
|
|
|
+ attachmentPathEmpty: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D1\u30B9\u3092\u7A7A\u306B\u3067\u304D\u307E\u305B\u3093\u3002",
|
|
|
|
|
+ attachmentPathIllegalChar: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D1\u30B9\u306B\u4E0D\u6B63\u306A\u30D5\u30A1\u30A4\u30EB\u540D\u6587\u5B57\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059\uFF1A{char}",
|
|
|
|
|
+ attachmentPathUnknownVariable: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D1\u30B9\u5185\u306E\u672A\u77E5\u306E\u5909\u6570\uFF1A{name}"
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// src/i18n/locales/en.ts
|
|
|
|
|
+var en = {
|
|
|
|
|
+ common: {
|
|
|
|
|
+ cancel: "Cancel"
|
|
|
|
|
+ },
|
|
|
|
|
+ settings: {
|
|
|
|
|
+ title: "Attachment Management Settings",
|
|
|
|
|
+ rootPath: {
|
|
|
|
|
+ name: "Root path to save attachment",
|
|
|
|
|
+ desc: "Select root path of attachment",
|
|
|
|
|
+ options: {
|
|
|
|
|
+ obsidian: "Copy Obsidian settings",
|
|
|
|
|
+ inFolder: "In the folder specified below",
|
|
|
|
|
+ nextToNote: "Next to note in folder specified below"
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ rootFolder: {
|
|
|
|
|
+ name: "Root folder",
|
|
|
|
|
+ desc: "Root folder of new attachment"
|
|
|
|
|
+ },
|
|
|
|
|
+ attachmentPath: {
|
|
|
|
|
+ name: "Attachment path",
|
|
|
|
|
+ desc: "Path of attachment in root folder, available variables ${notepath}, ${notename}, ${parent}"
|
|
|
|
|
+ },
|
|
|
|
|
+ attachmentFormat: {
|
|
|
|
|
+ name: "Attachment format",
|
|
|
|
|
+ desc: "Define how to name the attachment file, available variables ${date}, ${notename}, ${md5} and ${originalname}."
|
|
|
|
|
+ },
|
|
|
|
|
+ dateFormat: {
|
|
|
|
|
+ name: "Date format",
|
|
|
|
|
+ desc: "Moment date format to use",
|
|
|
|
|
+ linkText: "Moment format options"
|
|
|
|
|
+ },
|
|
|
|
|
+ autoRename: {
|
|
|
|
|
+ name: "Automatically rename attachment",
|
|
|
|
|
+ desc: "Automatically rename the attachment folder/filename when you rename the folder/filename where the corresponding md/canvas file be placed."
|
|
|
|
|
+ },
|
|
|
|
|
+ extensionOverride: {
|
|
|
|
|
+ name: "Extension override",
|
|
|
|
|
+ desc: "Using the extension override if you want to autorename the attachment with a specific extension (e.g. pdf or zip).",
|
|
|
|
|
+ addButton: "Add extension overrides",
|
|
|
|
|
+ extension: {
|
|
|
|
|
+ name: "Extension",
|
|
|
|
|
+ desc: "Extension to override",
|
|
|
|
|
+ placeholder: "pdf|docx?"
|
|
|
|
|
+ },
|
|
|
|
|
+ tooltips: {
|
|
|
|
|
+ remove: "Remove extension override",
|
|
|
|
|
+ edit: "Edit extension override",
|
|
|
|
|
+ save: "Save extension override"
|
|
|
|
|
+ },
|
|
|
|
|
+ saveNotice: "Saved extension override"
|
|
|
|
|
+ },
|
|
|
|
|
+ excludeExtension: {
|
|
|
|
|
+ name: "Exclude extension pattern",
|
|
|
|
|
+ desc: "Regex pattern to exclude certain extensions from being handled.",
|
|
|
|
|
+ placeholder: "pdf|docx?|xlsx?|pptx?|zip|rar"
|
|
|
|
|
+ },
|
|
|
|
|
+ excludedPaths: {
|
|
|
|
|
+ name: "Excluded paths",
|
|
|
|
|
+ desc: "Provide the full path of the folder names (case sensitive and without leading slash '/') divided by semicolon (;) to be excluded from renaming."
|
|
|
|
|
+ },
|
|
|
|
|
+ excludeSubpaths: {
|
|
|
|
|
+ name: "Exclude subpaths",
|
|
|
|
|
+ desc: "Turn on this option if you want to also exclude all subfolders of the folder paths provided above."
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ override: {
|
|
|
|
|
+ title: "Overriding Settings",
|
|
|
|
|
+ menuTitle: "Overriding attachment setting",
|
|
|
|
|
+ addExtensionOverrides: "Add extension overrides",
|
|
|
|
|
+ extension: {
|
|
|
|
|
+ name: "Extension",
|
|
|
|
|
+ desc: "Extension to override",
|
|
|
|
|
+ placeholder: "pdf"
|
|
|
|
|
+ },
|
|
|
|
|
+ buttons: {
|
|
|
|
|
+ reset: "Reset",
|
|
|
|
|
+ submit: "Submit"
|
|
|
|
|
+ },
|
|
|
|
|
+ notifications: {
|
|
|
|
|
+ reset: "Reset attachment setting of {path}",
|
|
|
|
|
+ overridden: "Overridden attachment setting of {path}"
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ extensionOverride: {
|
|
|
|
|
+ title: "Extension Override Settings",
|
|
|
|
|
+ rootPath: {
|
|
|
|
|
+ name: "Root path to save attachment",
|
|
|
|
|
+ desc: "Select root path of attachment for this extension"
|
|
|
|
|
+ },
|
|
|
|
|
+ rootFolder: {
|
|
|
|
|
+ name: "Root folder",
|
|
|
|
|
+ desc: "Root folder for this extension"
|
|
|
|
|
+ },
|
|
|
|
|
+ attachmentPath: {
|
|
|
|
|
+ name: "Attachment path",
|
|
|
|
|
+ desc: "Path of attachment in root folder for this extension"
|
|
|
|
|
+ },
|
|
|
|
|
+ attachmentFormat: {
|
|
|
|
|
+ name: "Attachment format",
|
|
|
|
|
+ desc: "Define how to name the attachment file for this extension"
|
|
|
|
|
+ },
|
|
|
|
|
+ buttons: {
|
|
|
|
|
+ save: "Save"
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ confirm: {
|
|
|
|
|
+ title: "Tips",
|
|
|
|
|
+ message: "This operation is irreversible and experimental. Please backup your vault first! Are you sure you want to continue?",
|
|
|
|
|
+ continue: "Yes"
|
|
|
|
|
+ },
|
|
|
|
|
+ notices: {
|
|
|
|
|
+ fileExcluded: "{path} was excluded",
|
|
|
|
|
+ overrideRemoved: "Removed override setting of {path}",
|
|
|
|
|
+ fileRenamed: "Renamed {from} to {to}",
|
|
|
|
|
+ filesRenamedBatch: "Renamed {count} attachments",
|
|
|
|
|
+ arrangeCompleted: "Arrange completed",
|
|
|
|
|
+ resetAttachmentSetting: "Reset attachment setting of {path}",
|
|
|
|
|
+ error: {
|
|
|
|
|
+ unknownError: "An unknown error occurred"
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ commands: {
|
|
|
|
|
+ rearrangeAllLinks: "Rearrange all linked attachments",
|
|
|
|
|
+ rearrangeActiveLinks: "Rearrange linked attachments",
|
|
|
|
|
+ resetOverrideSetting: "Reset override setting",
|
|
|
|
|
+ clearUnusedStorage: "Clear unused original name storage"
|
|
|
|
|
+ },
|
|
|
|
|
+ errors: {
|
|
|
|
|
+ canvasNotSupported: "Canvas is not supported as an extension override.",
|
|
|
|
|
+ markdownNotSupported: "Markdown is not supported as an extension override.",
|
|
|
|
|
+ extensionEmpty: "Extension override cannot be empty.",
|
|
|
|
|
+ duplicateExtension: "Duplicate extension override.",
|
|
|
|
|
+ excludedExtension: "Extension override cannot be an excluded extension.",
|
|
|
|
|
+ attachFormatEmpty: "Attachment format cannot be empty.",
|
|
|
|
|
+ attachFormatIllegalChar: "Attachment format contains illegal filename character: {char}",
|
|
|
|
|
+ attachFormatUnknownVariable: "Unknown variable in attachment format: {name}",
|
|
|
|
|
+ attachmentPathEmpty: "Attachment path cannot be empty.",
|
|
|
|
|
+ attachmentPathIllegalChar: "Attachment path contains illegal filename character: {char}",
|
|
|
|
|
+ attachmentPathUnknownVariable: "Unknown variable in attachment path: {name}"
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// src/i18n/locales/zh.ts
|
|
|
|
|
+var zhCn = {
|
|
|
|
|
+ common: {
|
|
|
|
|
+ cancel: "\u53D6\u6D88"
|
|
|
|
|
+ },
|
|
|
|
|
+ settings: {
|
|
|
|
|
+ title: "\u9644\u4EF6\u7BA1\u7406\u8BBE\u7F6E",
|
|
|
|
|
+ rootPath: {
|
|
|
|
|
+ name: "\u9644\u4EF6\u4FDD\u5B58\u6839\u8DEF\u5F84",
|
|
|
|
|
+ desc: "\u9009\u62E9\u9644\u4EF6\u7684\u6839\u8DEF\u5F84",
|
|
|
|
|
+ options: {
|
|
|
|
|
+ obsidian: "\u590D\u5236 Obsidian \u8BBE\u7F6E",
|
|
|
|
|
+ inFolder: "\u5728\u4E0B\u65B9\u6307\u5B9A\u7684\u6587\u4EF6\u5939\u4E2D",
|
|
|
|
|
+ nextToNote: "\u5728\u7B14\u8BB0\u65C1\u8FB9\u7684\u6307\u5B9A\u6587\u4EF6\u5939\u4E2D"
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ rootFolder: {
|
|
|
|
|
+ name: "\u6839\u6587\u4EF6\u5939",
|
|
|
|
|
+ desc: "\u65B0\u9644\u4EF6\u7684\u6839\u6587\u4EF6\u5939"
|
|
|
|
|
+ },
|
|
|
|
|
+ attachmentPath: {
|
|
|
|
|
+ name: "\u9644\u4EF6\u8DEF\u5F84",
|
|
|
|
|
+ desc: "\u9644\u4EF6\u5728\u6839\u6587\u4EF6\u5939\u4E2D\u7684\u8DEF\u5F84\uFF0C\u53EF\u7528\u53D8\u91CF ${notepath}\u3001${notename}\u3001${parent}"
|
|
|
|
|
+ },
|
|
|
|
|
+ attachmentFormat: {
|
|
|
|
|
+ name: "\u9644\u4EF6\u683C\u5F0F",
|
|
|
|
|
+ desc: "\u5B9A\u4E49\u5982\u4F55\u547D\u540D\u9644\u4EF6\u6587\u4EF6\uFF0C\u53EF\u7528\u53D8\u91CF ${date}\u3001${notename}\u3001${md5} \u548C ${originalname}\u3002"
|
|
|
|
|
+ },
|
|
|
|
|
+ dateFormat: {
|
|
|
|
|
+ name: "\u65E5\u671F\u683C\u5F0F",
|
|
|
|
|
+ desc: "\u4F7F\u7528\u7684 Moment \u65E5\u671F\u683C\u5F0F",
|
|
|
|
|
+ linkText: "Moment \u683C\u5F0F\u9009\u9879"
|
|
|
|
|
+ },
|
|
|
|
|
+ autoRename: {
|
|
|
|
|
+ name: "\u81EA\u52A8\u91CD\u547D\u540D\u9644\u4EF6",
|
|
|
|
|
+ desc: "\u5F53\u60A8\u91CD\u547D\u540D\u5BF9\u5E94 md/canvas \u6587\u4EF6\u6240\u5728\u7684\u6587\u4EF6\u5939/\u6587\u4EF6\u540D\u65F6\uFF0C\u81EA\u52A8\u91CD\u547D\u540D\u9644\u4EF6\u6587\u4EF6\u5939/\u6587\u4EF6\u540D\u3002"
|
|
|
|
|
+ },
|
|
|
|
|
+ extensionOverride: {
|
|
|
|
|
+ name: "\u6269\u5C55\u540D\u8986\u76D6",
|
|
|
|
|
+ desc: "\u5982\u679C\u60A8\u60F3\u8981\u5BF9\u7279\u5B9A\u6269\u5C55\u540D\u7684\u9644\u4EF6\u8FDB\u884C\u81EA\u52A8\u91CD\u547D\u540D\uFF08\u4F8B\u5982 pdf \u6216 zip),\u8BF7\u4F7F\u7528\u6269\u5C55\u540D\u8986\u76D6\u3002",
|
|
|
|
|
+ addButton: "\u6DFB\u52A0\u6269\u5C55\u540D\u8986\u76D6",
|
|
|
|
|
+ extension: {
|
|
|
|
|
+ name: "\u6269\u5C55\u540D",
|
|
|
|
|
+ desc: "\u8981\u8986\u76D6\u7684\u6269\u5C55\u540D",
|
|
|
|
|
+ placeholder: "pdf|docx?"
|
|
|
|
|
+ },
|
|
|
|
|
+ tooltips: {
|
|
|
|
|
+ remove: "\u79FB\u9664\u6269\u5C55\u540D\u8986\u76D6",
|
|
|
|
|
+ edit: "\u7F16\u8F91\u6269\u5C55\u540D\u8986\u76D6",
|
|
|
|
|
+ save: "\u4FDD\u5B58\u6269\u5C55\u540D\u8986\u76D6"
|
|
|
|
|
+ },
|
|
|
|
|
+ saveNotice: "\u5DF2\u4FDD\u5B58\u6269\u5C55\u540D\u8986\u76D6"
|
|
|
|
|
+ },
|
|
|
|
|
+ excludeExtension: {
|
|
|
|
|
+ name: "\u6392\u9664\u6269\u5C55\u540D\u6A21\u5F0F",
|
|
|
|
|
+ desc: "\u7528\u4E8E\u6392\u9664\u67D0\u4E9B\u6269\u5C55\u540D\u4E0D\u88AB\u5904\u7406\u7684\u6B63\u5219\u8868\u8FBE\u5F0F\u6A21\u5F0F\u3002",
|
|
|
|
|
+ placeholder: "pdf|docx?|xlsx?|pptx?|zip|rar"
|
|
|
|
|
+ },
|
|
|
|
|
+ excludedPaths: {
|
|
|
|
|
+ name: "\u6392\u9664\u8DEF\u5F84",
|
|
|
|
|
+ desc: "\u63D0\u4F9B\u8981\u4ECE\u91CD\u547D\u540D\u4E2D\u6392\u9664\u7684\u6587\u4EF6\u5939\u540D\u79F0\u7684\u5B8C\u6574\u8DEF\u5F84\uFF08\u533A\u5206\u5927\u5C0F\u5199\u4E14\u4E0D\u5E26\u524D\u5BFC\u659C\u6760 '/'\uFF09\uFF0C\u7528\u5206\u53F7\uFF08;\uFF09\u5206\u9694\u3002"
|
|
|
|
|
+ },
|
|
|
|
|
+ excludeSubpaths: {
|
|
|
|
|
+ name: "\u6392\u9664\u5B50\u8DEF\u5F84",
|
|
|
|
|
+ desc: "\u5982\u679C\u60A8\u8FD8\u60F3\u6392\u9664\u4E0A\u9762\u63D0\u4F9B\u7684\u6587\u4EF6\u5939\u8DEF\u5F84\u7684\u6240\u6709\u5B50\u6587\u4EF6\u5939\uFF0C\u8BF7\u6253\u5F00\u6B64\u9009\u9879\u3002"
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ override: {
|
|
|
|
|
+ title: "\u8986\u76D6\u8BBE\u7F6E",
|
|
|
|
|
+ menuTitle: "\u8986\u76D6\u9644\u4EF6\u8BBE\u7F6E",
|
|
|
|
|
+ addExtensionOverrides: "\u6DFB\u52A0\u6269\u5C55\u540D\u8986\u76D6",
|
|
|
|
|
+ extension: {
|
|
|
|
|
+ name: "\u6269\u5C55\u540D",
|
|
|
|
|
+ desc: "\u8981\u8986\u76D6\u7684\u6269\u5C55\u540D",
|
|
|
|
|
+ placeholder: "pdf"
|
|
|
|
|
+ },
|
|
|
|
|
+ buttons: {
|
|
|
|
|
+ reset: "\u91CD\u7F6E",
|
|
|
|
|
+ submit: "\u63D0\u4EA4"
|
|
|
|
|
+ },
|
|
|
|
|
+ notifications: {
|
|
|
|
|
+ reset: "\u5DF2\u91CD\u7F6E {path} \u7684\u9644\u4EF6\u8BBE\u7F6E",
|
|
|
|
|
+ overridden: "\u5DF2\u8986\u76D6 {path} \u7684\u9644\u4EF6\u8BBE\u7F6E"
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ extensionOverride: {
|
|
|
|
|
+ title: "\u6269\u5C55\u540D\u8986\u76D6\u8BBE\u7F6E",
|
|
|
|
|
+ rootPath: {
|
|
|
|
|
+ name: "\u9644\u4EF6\u4FDD\u5B58\u6839\u8DEF\u5F84",
|
|
|
|
|
+ desc: "\u9009\u62E9\u6B64\u6269\u5C55\u540D\u7684\u9644\u4EF6\u6839\u8DEF\u5F84"
|
|
|
|
|
+ },
|
|
|
|
|
+ rootFolder: {
|
|
|
|
|
+ name: "\u6839\u6587\u4EF6\u5939",
|
|
|
|
|
+ desc: "\u6B64\u6269\u5C55\u540D\u7684\u6839\u6587\u4EF6\u5939"
|
|
|
|
|
+ },
|
|
|
|
|
+ attachmentPath: {
|
|
|
|
|
+ name: "\u9644\u4EF6\u8DEF\u5F84",
|
|
|
|
|
+ desc: "\u6B64\u6269\u5C55\u540D\u5728\u6839\u6587\u4EF6\u5939\u4E2D\u7684\u9644\u4EF6\u8DEF\u5F84"
|
|
|
|
|
+ },
|
|
|
|
|
+ attachmentFormat: {
|
|
|
|
|
+ name: "\u9644\u4EF6\u683C\u5F0F",
|
|
|
|
|
+ desc: "\u5B9A\u4E49\u6B64\u6269\u5C55\u540D\u7684\u9644\u4EF6\u6587\u4EF6\u547D\u540D\u65B9\u5F0F"
|
|
|
|
|
+ },
|
|
|
|
|
+ buttons: {
|
|
|
|
|
+ save: "\u4FDD\u5B58"
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ confirm: {
|
|
|
|
|
+ title: "\u63D0\u793A",
|
|
|
|
|
+ message: "\u6B64\u64CD\u4F5C\u4E0D\u53EF\u9006\u4E14\u4E3A\u5B9E\u9A8C\u6027\u529F\u80FD\uFF0C\u8BF7\u5148\u5907\u4EFD\u60A8\u7684\u5E93\uFF01\u786E\u5B9A\u8981\u7EE7\u7EED\u5417\uFF1F",
|
|
|
|
|
+ continue: "\u7EE7\u7EED"
|
|
|
|
|
+ },
|
|
|
|
|
+ notices: {
|
|
|
|
|
+ fileExcluded: "{path} \u5DF2\u88AB\u6392\u9664",
|
|
|
|
|
+ overrideRemoved: "\u5DF2\u79FB\u9664 {path} \u7684\u8986\u76D6\u8BBE\u7F6E",
|
|
|
|
|
+ fileRenamed: "\u5DF2\u5C06 {from} \u91CD\u547D\u540D\u4E3A {to}",
|
|
|
|
|
+ filesRenamedBatch: "\u5DF2\u91CD\u547D\u540D {count} \u4E2A\u9644\u4EF6",
|
|
|
|
|
+ arrangeCompleted: "\u6574\u7406\u5B8C\u6210",
|
|
|
|
|
+ resetAttachmentSetting: "\u5DF2\u91CD\u7F6E {path} \u7684\u9644\u4EF6\u8BBE\u7F6E",
|
|
|
|
|
+ error: {
|
|
|
|
|
+ unknownError: "\u53D1\u751F\u672A\u77E5\u9519\u8BEF"
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ commands: {
|
|
|
|
|
+ rearrangeAllLinks: "\u91CD\u65B0\u6574\u7406\u6240\u6709\u94FE\u63A5\u7684\u9644\u4EF6",
|
|
|
|
|
+ rearrangeActiveLinks: "\u91CD\u65B0\u6574\u7406\u94FE\u63A5\u7684\u9644\u4EF6",
|
|
|
|
|
+ resetOverrideSetting: "\u91CD\u7F6E\u8986\u76D6\u8BBE\u7F6E",
|
|
|
|
|
+ clearUnusedStorage: "\u6E05\u7406\u672A\u4F7F\u7528\u7684\u539F\u59CB\u6587\u4EF6\u540D\u5B58\u50A8"
|
|
|
|
|
+ },
|
|
|
|
|
+ errors: {
|
|
|
|
|
+ canvasNotSupported: "\u4E0D\u652F\u6301\u5C06 Canvas \u4F5C\u4E3A\u6269\u5C55\u8986\u76D6\u3002",
|
|
|
|
|
+ markdownNotSupported: "\u4E0D\u652F\u6301\u5C06 Markdown \u4F5C\u4E3A\u6269\u5C55\u8986\u76D6\u3002",
|
|
|
|
|
+ extensionEmpty: "\u6269\u5C55\u8986\u76D6\u4E0D\u80FD\u4E3A\u7A7A\u3002",
|
|
|
|
|
+ duplicateExtension: "\u91CD\u590D\u7684\u6269\u5C55\u8986\u76D6\u3002",
|
|
|
|
|
+ excludedExtension: "\u6269\u5C55\u8986\u76D6\u4E0D\u80FD\u662F\u88AB\u6392\u9664\u7684\u6269\u5C55\u3002",
|
|
|
|
|
+ attachFormatEmpty: "\u9644\u4EF6\u683C\u5F0F\u4E0D\u80FD\u4E3A\u7A7A\u3002",
|
|
|
|
|
+ attachFormatIllegalChar: "\u9644\u4EF6\u683C\u5F0F\u5305\u542B\u975E\u6CD5\u6587\u4EF6\u540D\u5B57\u7B26\uFF1A{char}",
|
|
|
|
|
+ attachFormatUnknownVariable: "\u9644\u4EF6\u683C\u5F0F\u4E2D\u5B58\u5728\u672A\u77E5\u53D8\u91CF\uFF1A{name}",
|
|
|
|
|
+ attachmentPathEmpty: "\u9644\u4EF6\u8DEF\u5F84\u4E0D\u80FD\u4E3A\u7A7A\u3002",
|
|
|
|
|
+ attachmentPathIllegalChar: "\u9644\u4EF6\u8DEF\u5F84\u5305\u542B\u975E\u6CD5\u6587\u4EF6\u540D\u5B57\u7B26\uFF1A{char}",
|
|
|
|
|
+ attachmentPathUnknownVariable: "\u9644\u4EF6\u8DEF\u5F84\u4E2D\u5B58\u5728\u672A\u77E5\u53D8\u91CF\uFF1A{name}"
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// src/i18n/loader.ts
|
|
|
|
|
+function loadAllTranslations() {
|
|
|
|
|
+ registerTranslations("en", en);
|
|
|
|
|
+ registerTranslations("zh", zhCn);
|
|
|
|
|
+ registerTranslations("ja", ja);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// src/i18n/index.ts
|
|
|
|
|
+var currentLanguage = "en";
|
|
|
|
|
+var translations = {
|
|
|
|
|
+ en: {},
|
|
|
|
|
+ zh: {},
|
|
|
|
|
+ ja: {}
|
|
|
|
|
+};
|
|
|
|
|
+function setLanguage(language) {
|
|
|
|
|
+ currentLanguage = language;
|
|
|
|
|
+}
|
|
|
|
|
+function registerTranslations(language, translationMap) {
|
|
|
|
|
+ translations[language] = { ...translations[language], ...translationMap };
|
|
|
|
|
+}
|
|
|
|
|
+function t(key, ...args) {
|
|
|
|
|
+ const params = args[0];
|
|
|
|
|
+ const keys = key.split(".");
|
|
|
|
|
+ let value = translations[currentLanguage];
|
|
|
|
|
+ for (const k of keys) {
|
|
|
|
|
+ if (value && typeof value === "object" && k in value) {
|
|
|
|
|
+ value = value[k];
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (currentLanguage !== "en") {
|
|
|
|
|
+ let fallbackValue = translations["en"];
|
|
|
|
|
+ for (const fk of keys) {
|
|
|
|
|
+ if (fallbackValue && typeof fallbackValue === "object" && fk in fallbackValue) {
|
|
|
|
|
+ fallbackValue = fallbackValue[fk];
|
|
|
|
|
+ } else {
|
|
|
|
|
+ fallbackValue = key;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ value = fallbackValue;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ value = key;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ let result = typeof value === "string" ? value : key;
|
|
|
|
|
+ if (params) {
|
|
|
|
|
+ Object.entries(params).forEach(([paramKey, paramValue]) => {
|
|
|
|
|
+ result = result.replace(new RegExp(`\\{${paramKey}\\}`, "g"), String(paramValue));
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+}
|
|
|
|
|
+function detectLanguage() {
|
|
|
|
|
+ const locale = import_obsidian.moment.locale();
|
|
|
|
|
+ if (locale.startsWith("zh")) {
|
|
|
|
|
+ return "zh";
|
|
|
|
|
+ }
|
|
|
|
|
+ if (locale.startsWith("ja")) {
|
|
|
|
|
+ return "ja";
|
|
|
|
|
+ }
|
|
|
|
|
+ return "en";
|
|
|
|
|
+}
|
|
|
|
|
+function initI18n(language) {
|
|
|
|
|
+ loadAllTranslations();
|
|
|
|
|
+ const initialLanguage = language || detectLanguage();
|
|
|
|
|
+ setLanguage(initialLanguage);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// node_modules/.pnpm/ts-md5@1.3.1/node_modules/ts-md5/dist/esm/md5.js
|
|
|
|
|
+var Md5 = class _Md5 {
|
|
|
|
|
+ constructor() {
|
|
|
|
|
+ this._dataLength = 0;
|
|
|
|
|
+ this._bufferLength = 0;
|
|
|
|
|
+ this._state = new Int32Array(4);
|
|
|
|
|
+ this._buffer = new ArrayBuffer(68);
|
|
|
|
|
+ this._buffer8 = new Uint8Array(this._buffer, 0, 68);
|
|
|
|
|
+ this._buffer32 = new Uint32Array(this._buffer, 0, 17);
|
|
|
|
|
+ this.start();
|
|
|
|
|
+ }
|
|
|
|
|
+ static hashStr(str, raw = false) {
|
|
|
|
|
+ return this.onePassHasher.start().appendStr(str).end(raw);
|
|
|
|
|
+ }
|
|
|
|
|
+ static hashAsciiStr(str, raw = false) {
|
|
|
|
|
+ return this.onePassHasher.start().appendAsciiStr(str).end(raw);
|
|
|
|
|
+ }
|
|
|
|
|
+ static _hex(x) {
|
|
|
|
|
+ const hc = _Md5.hexChars;
|
|
|
|
|
+ const ho = _Md5.hexOut;
|
|
|
|
|
+ let n;
|
|
|
|
|
+ let offset;
|
|
|
|
|
+ let j;
|
|
|
|
|
+ let i;
|
|
|
|
|
+ for (i = 0; i < 4; i += 1) {
|
|
|
|
|
+ offset = i * 8;
|
|
|
|
|
+ n = x[i];
|
|
|
|
|
+ for (j = 0; j < 8; j += 2) {
|
|
|
|
|
+ ho[offset + 1 + j] = hc.charAt(n & 15);
|
|
|
|
|
+ n >>>= 4;
|
|
|
|
|
+ ho[offset + 0 + j] = hc.charAt(n & 15);
|
|
|
|
|
+ n >>>= 4;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return ho.join("");
|
|
|
|
|
+ }
|
|
|
|
|
+ static _md5cycle(x, k) {
|
|
|
|
|
+ let a = x[0];
|
|
|
|
|
+ let b = x[1];
|
|
|
|
|
+ let c = x[2];
|
|
|
|
|
+ let d = x[3];
|
|
|
|
|
+ a += (b & c | ~b & d) + k[0] - 680876936 | 0;
|
|
|
|
|
+ a = (a << 7 | a >>> 25) + b | 0;
|
|
|
|
|
+ d += (a & b | ~a & c) + k[1] - 389564586 | 0;
|
|
|
|
|
+ d = (d << 12 | d >>> 20) + a | 0;
|
|
|
|
|
+ c += (d & a | ~d & b) + k[2] + 606105819 | 0;
|
|
|
|
|
+ c = (c << 17 | c >>> 15) + d | 0;
|
|
|
|
|
+ b += (c & d | ~c & a) + k[3] - 1044525330 | 0;
|
|
|
|
|
+ b = (b << 22 | b >>> 10) + c | 0;
|
|
|
|
|
+ a += (b & c | ~b & d) + k[4] - 176418897 | 0;
|
|
|
|
|
+ a = (a << 7 | a >>> 25) + b | 0;
|
|
|
|
|
+ d += (a & b | ~a & c) + k[5] + 1200080426 | 0;
|
|
|
|
|
+ d = (d << 12 | d >>> 20) + a | 0;
|
|
|
|
|
+ c += (d & a | ~d & b) + k[6] - 1473231341 | 0;
|
|
|
|
|
+ c = (c << 17 | c >>> 15) + d | 0;
|
|
|
|
|
+ b += (c & d | ~c & a) + k[7] - 45705983 | 0;
|
|
|
|
|
+ b = (b << 22 | b >>> 10) + c | 0;
|
|
|
|
|
+ a += (b & c | ~b & d) + k[8] + 1770035416 | 0;
|
|
|
|
|
+ a = (a << 7 | a >>> 25) + b | 0;
|
|
|
|
|
+ d += (a & b | ~a & c) + k[9] - 1958414417 | 0;
|
|
|
|
|
+ d = (d << 12 | d >>> 20) + a | 0;
|
|
|
|
|
+ c += (d & a | ~d & b) + k[10] - 42063 | 0;
|
|
|
|
|
+ c = (c << 17 | c >>> 15) + d | 0;
|
|
|
|
|
+ b += (c & d | ~c & a) + k[11] - 1990404162 | 0;
|
|
|
|
|
+ b = (b << 22 | b >>> 10) + c | 0;
|
|
|
|
|
+ a += (b & c | ~b & d) + k[12] + 1804603682 | 0;
|
|
|
|
|
+ a = (a << 7 | a >>> 25) + b | 0;
|
|
|
|
|
+ d += (a & b | ~a & c) + k[13] - 40341101 | 0;
|
|
|
|
|
+ d = (d << 12 | d >>> 20) + a | 0;
|
|
|
|
|
+ c += (d & a | ~d & b) + k[14] - 1502002290 | 0;
|
|
|
|
|
+ c = (c << 17 | c >>> 15) + d | 0;
|
|
|
|
|
+ b += (c & d | ~c & a) + k[15] + 1236535329 | 0;
|
|
|
|
|
+ b = (b << 22 | b >>> 10) + c | 0;
|
|
|
|
|
+ a += (b & d | c & ~d) + k[1] - 165796510 | 0;
|
|
|
|
|
+ a = (a << 5 | a >>> 27) + b | 0;
|
|
|
|
|
+ d += (a & c | b & ~c) + k[6] - 1069501632 | 0;
|
|
|
|
|
+ d = (d << 9 | d >>> 23) + a | 0;
|
|
|
|
|
+ c += (d & b | a & ~b) + k[11] + 643717713 | 0;
|
|
|
|
|
+ c = (c << 14 | c >>> 18) + d | 0;
|
|
|
|
|
+ b += (c & a | d & ~a) + k[0] - 373897302 | 0;
|
|
|
|
|
+ b = (b << 20 | b >>> 12) + c | 0;
|
|
|
|
|
+ a += (b & d | c & ~d) + k[5] - 701558691 | 0;
|
|
|
|
|
+ a = (a << 5 | a >>> 27) + b | 0;
|
|
|
|
|
+ d += (a & c | b & ~c) + k[10] + 38016083 | 0;
|
|
|
|
|
+ d = (d << 9 | d >>> 23) + a | 0;
|
|
|
|
|
+ c += (d & b | a & ~b) + k[15] - 660478335 | 0;
|
|
|
|
|
+ c = (c << 14 | c >>> 18) + d | 0;
|
|
|
|
|
+ b += (c & a | d & ~a) + k[4] - 405537848 | 0;
|
|
|
|
|
+ b = (b << 20 | b >>> 12) + c | 0;
|
|
|
|
|
+ a += (b & d | c & ~d) + k[9] + 568446438 | 0;
|
|
|
|
|
+ a = (a << 5 | a >>> 27) + b | 0;
|
|
|
|
|
+ d += (a & c | b & ~c) + k[14] - 1019803690 | 0;
|
|
|
|
|
+ d = (d << 9 | d >>> 23) + a | 0;
|
|
|
|
|
+ c += (d & b | a & ~b) + k[3] - 187363961 | 0;
|
|
|
|
|
+ c = (c << 14 | c >>> 18) + d | 0;
|
|
|
|
|
+ b += (c & a | d & ~a) + k[8] + 1163531501 | 0;
|
|
|
|
|
+ b = (b << 20 | b >>> 12) + c | 0;
|
|
|
|
|
+ a += (b & d | c & ~d) + k[13] - 1444681467 | 0;
|
|
|
|
|
+ a = (a << 5 | a >>> 27) + b | 0;
|
|
|
|
|
+ d += (a & c | b & ~c) + k[2] - 51403784 | 0;
|
|
|
|
|
+ d = (d << 9 | d >>> 23) + a | 0;
|
|
|
|
|
+ c += (d & b | a & ~b) + k[7] + 1735328473 | 0;
|
|
|
|
|
+ c = (c << 14 | c >>> 18) + d | 0;
|
|
|
|
|
+ b += (c & a | d & ~a) + k[12] - 1926607734 | 0;
|
|
|
|
|
+ b = (b << 20 | b >>> 12) + c | 0;
|
|
|
|
|
+ a += (b ^ c ^ d) + k[5] - 378558 | 0;
|
|
|
|
|
+ a = (a << 4 | a >>> 28) + b | 0;
|
|
|
|
|
+ d += (a ^ b ^ c) + k[8] - 2022574463 | 0;
|
|
|
|
|
+ d = (d << 11 | d >>> 21) + a | 0;
|
|
|
|
|
+ c += (d ^ a ^ b) + k[11] + 1839030562 | 0;
|
|
|
|
|
+ c = (c << 16 | c >>> 16) + d | 0;
|
|
|
|
|
+ b += (c ^ d ^ a) + k[14] - 35309556 | 0;
|
|
|
|
|
+ b = (b << 23 | b >>> 9) + c | 0;
|
|
|
|
|
+ a += (b ^ c ^ d) + k[1] - 1530992060 | 0;
|
|
|
|
|
+ a = (a << 4 | a >>> 28) + b | 0;
|
|
|
|
|
+ d += (a ^ b ^ c) + k[4] + 1272893353 | 0;
|
|
|
|
|
+ d = (d << 11 | d >>> 21) + a | 0;
|
|
|
|
|
+ c += (d ^ a ^ b) + k[7] - 155497632 | 0;
|
|
|
|
|
+ c = (c << 16 | c >>> 16) + d | 0;
|
|
|
|
|
+ b += (c ^ d ^ a) + k[10] - 1094730640 | 0;
|
|
|
|
|
+ b = (b << 23 | b >>> 9) + c | 0;
|
|
|
|
|
+ a += (b ^ c ^ d) + k[13] + 681279174 | 0;
|
|
|
|
|
+ a = (a << 4 | a >>> 28) + b | 0;
|
|
|
|
|
+ d += (a ^ b ^ c) + k[0] - 358537222 | 0;
|
|
|
|
|
+ d = (d << 11 | d >>> 21) + a | 0;
|
|
|
|
|
+ c += (d ^ a ^ b) + k[3] - 722521979 | 0;
|
|
|
|
|
+ c = (c << 16 | c >>> 16) + d | 0;
|
|
|
|
|
+ b += (c ^ d ^ a) + k[6] + 76029189 | 0;
|
|
|
|
|
+ b = (b << 23 | b >>> 9) + c | 0;
|
|
|
|
|
+ a += (b ^ c ^ d) + k[9] - 640364487 | 0;
|
|
|
|
|
+ a = (a << 4 | a >>> 28) + b | 0;
|
|
|
|
|
+ d += (a ^ b ^ c) + k[12] - 421815835 | 0;
|
|
|
|
|
+ d = (d << 11 | d >>> 21) + a | 0;
|
|
|
|
|
+ c += (d ^ a ^ b) + k[15] + 530742520 | 0;
|
|
|
|
|
+ c = (c << 16 | c >>> 16) + d | 0;
|
|
|
|
|
+ b += (c ^ d ^ a) + k[2] - 995338651 | 0;
|
|
|
|
|
+ b = (b << 23 | b >>> 9) + c | 0;
|
|
|
|
|
+ a += (c ^ (b | ~d)) + k[0] - 198630844 | 0;
|
|
|
|
|
+ a = (a << 6 | a >>> 26) + b | 0;
|
|
|
|
|
+ d += (b ^ (a | ~c)) + k[7] + 1126891415 | 0;
|
|
|
|
|
+ d = (d << 10 | d >>> 22) + a | 0;
|
|
|
|
|
+ c += (a ^ (d | ~b)) + k[14] - 1416354905 | 0;
|
|
|
|
|
+ c = (c << 15 | c >>> 17) + d | 0;
|
|
|
|
|
+ b += (d ^ (c | ~a)) + k[5] - 57434055 | 0;
|
|
|
|
|
+ b = (b << 21 | b >>> 11) + c | 0;
|
|
|
|
|
+ a += (c ^ (b | ~d)) + k[12] + 1700485571 | 0;
|
|
|
|
|
+ a = (a << 6 | a >>> 26) + b | 0;
|
|
|
|
|
+ d += (b ^ (a | ~c)) + k[3] - 1894986606 | 0;
|
|
|
|
|
+ d = (d << 10 | d >>> 22) + a | 0;
|
|
|
|
|
+ c += (a ^ (d | ~b)) + k[10] - 1051523 | 0;
|
|
|
|
|
+ c = (c << 15 | c >>> 17) + d | 0;
|
|
|
|
|
+ b += (d ^ (c | ~a)) + k[1] - 2054922799 | 0;
|
|
|
|
|
+ b = (b << 21 | b >>> 11) + c | 0;
|
|
|
|
|
+ a += (c ^ (b | ~d)) + k[8] + 1873313359 | 0;
|
|
|
|
|
+ a = (a << 6 | a >>> 26) + b | 0;
|
|
|
|
|
+ d += (b ^ (a | ~c)) + k[15] - 30611744 | 0;
|
|
|
|
|
+ d = (d << 10 | d >>> 22) + a | 0;
|
|
|
|
|
+ c += (a ^ (d | ~b)) + k[6] - 1560198380 | 0;
|
|
|
|
|
+ c = (c << 15 | c >>> 17) + d | 0;
|
|
|
|
|
+ b += (d ^ (c | ~a)) + k[13] + 1309151649 | 0;
|
|
|
|
|
+ b = (b << 21 | b >>> 11) + c | 0;
|
|
|
|
|
+ a += (c ^ (b | ~d)) + k[4] - 145523070 | 0;
|
|
|
|
|
+ a = (a << 6 | a >>> 26) + b | 0;
|
|
|
|
|
+ d += (b ^ (a | ~c)) + k[11] - 1120210379 | 0;
|
|
|
|
|
+ d = (d << 10 | d >>> 22) + a | 0;
|
|
|
|
|
+ c += (a ^ (d | ~b)) + k[2] + 718787259 | 0;
|
|
|
|
|
+ c = (c << 15 | c >>> 17) + d | 0;
|
|
|
|
|
+ b += (d ^ (c | ~a)) + k[9] - 343485551 | 0;
|
|
|
|
|
+ b = (b << 21 | b >>> 11) + c | 0;
|
|
|
|
|
+ x[0] = a + x[0] | 0;
|
|
|
|
|
+ x[1] = b + x[1] | 0;
|
|
|
|
|
+ x[2] = c + x[2] | 0;
|
|
|
|
|
+ x[3] = d + x[3] | 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Initialise buffer to be hashed
|
|
|
|
|
+ */
|
|
|
|
|
+ start() {
|
|
|
|
|
+ this._dataLength = 0;
|
|
|
|
|
+ this._bufferLength = 0;
|
|
|
|
|
+ this._state.set(_Md5.stateIdentity);
|
|
|
|
|
+ return this;
|
|
|
|
|
+ }
|
|
|
|
|
+ // Char to code point to to array conversion:
|
|
|
|
|
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt
|
|
|
|
|
+ // #Example.3A_Fixing_charCodeAt_to_handle_non-Basic-Multilingual-Plane_characters_if_their_presence_earlier_in_the_string_is_unknown
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Append a UTF-8 string to the hash buffer
|
|
|
|
|
+ * @param str String to append
|
|
|
|
|
+ */
|
|
|
|
|
+ appendStr(str) {
|
|
|
|
|
+ const buf8 = this._buffer8;
|
|
|
|
|
+ const buf32 = this._buffer32;
|
|
|
|
|
+ let bufLen = this._bufferLength;
|
|
|
|
|
+ let code;
|
|
|
|
|
+ let i;
|
|
|
|
|
+ for (i = 0; i < str.length; i += 1) {
|
|
|
|
|
+ code = str.charCodeAt(i);
|
|
|
|
|
+ if (code < 128) {
|
|
|
|
|
+ buf8[bufLen++] = code;
|
|
|
|
|
+ } else if (code < 2048) {
|
|
|
|
|
+ buf8[bufLen++] = (code >>> 6) + 192;
|
|
|
|
|
+ buf8[bufLen++] = code & 63 | 128;
|
|
|
|
|
+ } else if (code < 55296 || code > 56319) {
|
|
|
|
|
+ buf8[bufLen++] = (code >>> 12) + 224;
|
|
|
|
|
+ buf8[bufLen++] = code >>> 6 & 63 | 128;
|
|
|
|
|
+ buf8[bufLen++] = code & 63 | 128;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ code = (code - 55296) * 1024 + (str.charCodeAt(++i) - 56320) + 65536;
|
|
|
|
|
+ if (code > 1114111) {
|
|
|
|
|
+ throw new Error("Unicode standard supports code points up to U+10FFFF");
|
|
|
|
|
+ }
|
|
|
|
|
+ buf8[bufLen++] = (code >>> 18) + 240;
|
|
|
|
|
+ buf8[bufLen++] = code >>> 12 & 63 | 128;
|
|
|
|
|
+ buf8[bufLen++] = code >>> 6 & 63 | 128;
|
|
|
|
|
+ buf8[bufLen++] = code & 63 | 128;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (bufLen >= 64) {
|
|
|
|
|
+ this._dataLength += 64;
|
|
|
|
|
+ _Md5._md5cycle(this._state, buf32);
|
|
|
|
|
+ bufLen -= 64;
|
|
|
|
|
+ buf32[0] = buf32[16];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ this._bufferLength = bufLen;
|
|
|
|
|
+ return this;
|
|
|
|
|
+ }
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Append an ASCII string to the hash buffer
|
|
|
|
|
+ * @param str String to append
|
|
|
|
|
+ */
|
|
|
|
|
+ appendAsciiStr(str) {
|
|
|
|
|
+ const buf8 = this._buffer8;
|
|
|
|
|
+ const buf32 = this._buffer32;
|
|
|
|
|
+ let bufLen = this._bufferLength;
|
|
|
|
|
+ let i;
|
|
|
|
|
+ let j = 0;
|
|
|
|
|
+ for (; ; ) {
|
|
|
|
|
+ i = Math.min(str.length - j, 64 - bufLen);
|
|
|
|
|
+ while (i--) {
|
|
|
|
|
+ buf8[bufLen++] = str.charCodeAt(j++);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (bufLen < 64) {
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ this._dataLength += 64;
|
|
|
|
|
+ _Md5._md5cycle(this._state, buf32);
|
|
|
|
|
+ bufLen = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ this._bufferLength = bufLen;
|
|
|
|
|
+ return this;
|
|
|
|
|
+ }
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Append a byte array to the hash buffer
|
|
|
|
|
+ * @param input array to append
|
|
|
|
|
+ */
|
|
|
|
|
+ appendByteArray(input) {
|
|
|
|
|
+ const buf8 = this._buffer8;
|
|
|
|
|
+ const buf32 = this._buffer32;
|
|
|
|
|
+ let bufLen = this._bufferLength;
|
|
|
|
|
+ let i;
|
|
|
|
|
+ let j = 0;
|
|
|
|
|
+ for (; ; ) {
|
|
|
|
|
+ i = Math.min(input.length - j, 64 - bufLen);
|
|
|
|
|
+ while (i--) {
|
|
|
|
|
+ buf8[bufLen++] = input[j++];
|
|
|
|
|
+ }
|
|
|
|
|
+ if (bufLen < 64) {
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ this._dataLength += 64;
|
|
|
|
|
+ _Md5._md5cycle(this._state, buf32);
|
|
|
|
|
+ bufLen = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ this._bufferLength = bufLen;
|
|
|
|
|
+ return this;
|
|
|
|
|
+ }
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Get the state of the hash buffer
|
|
|
|
|
+ */
|
|
|
|
|
+ getState() {
|
|
|
|
|
+ const s = this._state;
|
|
|
|
|
+ return {
|
|
|
|
|
+ buffer: String.fromCharCode.apply(null, Array.from(this._buffer8)),
|
|
|
|
|
+ buflen: this._bufferLength,
|
|
|
|
|
+ length: this._dataLength,
|
|
|
|
|
+ state: [s[0], s[1], s[2], s[3]]
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Override the current state of the hash buffer
|
|
|
|
|
+ * @param state New hash buffer state
|
|
|
|
|
+ */
|
|
|
|
|
+ setState(state) {
|
|
|
|
|
+ const buf = state.buffer;
|
|
|
|
|
+ const x = state.state;
|
|
|
|
|
+ const s = this._state;
|
|
|
|
|
+ let i;
|
|
|
|
|
+ this._dataLength = state.length;
|
|
|
|
|
+ this._bufferLength = state.buflen;
|
|
|
|
|
+ s[0] = x[0];
|
|
|
|
|
+ s[1] = x[1];
|
|
|
|
|
+ s[2] = x[2];
|
|
|
|
|
+ s[3] = x[3];
|
|
|
|
|
+ for (i = 0; i < buf.length; i += 1) {
|
|
|
|
|
+ this._buffer8[i] = buf.charCodeAt(i);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Hash the current state of the hash buffer and return the result
|
|
|
|
|
+ * @param raw Whether to return the value as an `Int32Array`
|
|
|
|
|
+ */
|
|
|
|
|
+ end(raw = false) {
|
|
|
|
|
+ const bufLen = this._bufferLength;
|
|
|
|
|
+ const buf8 = this._buffer8;
|
|
|
|
|
+ const buf32 = this._buffer32;
|
|
|
|
|
+ const i = (bufLen >> 2) + 1;
|
|
|
|
|
+ this._dataLength += bufLen;
|
|
|
|
|
+ const dataBitsLen = this._dataLength * 8;
|
|
|
|
|
+ buf8[bufLen] = 128;
|
|
|
|
|
+ buf8[bufLen + 1] = buf8[bufLen + 2] = buf8[bufLen + 3] = 0;
|
|
|
|
|
+ buf32.set(_Md5.buffer32Identity.subarray(i), i);
|
|
|
|
|
+ if (bufLen > 55) {
|
|
|
|
|
+ _Md5._md5cycle(this._state, buf32);
|
|
|
|
|
+ buf32.set(_Md5.buffer32Identity);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (dataBitsLen <= 4294967295) {
|
|
|
|
|
+ buf32[14] = dataBitsLen;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ const matches = dataBitsLen.toString(16).match(/(.*?)(.{0,8})$/);
|
|
|
|
|
+ if (matches === null) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ const lo = parseInt(matches[2], 16);
|
|
|
|
|
+ const hi = parseInt(matches[1], 16) || 0;
|
|
|
|
|
+ buf32[14] = lo;
|
|
|
|
|
+ buf32[15] = hi;
|
|
|
|
|
+ }
|
|
|
|
|
+ _Md5._md5cycle(this._state, buf32);
|
|
|
|
|
+ return raw ? this._state : _Md5._hex(this._state);
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+Md5.stateIdentity = new Int32Array([1732584193, -271733879, -1732584194, 271733878]);
|
|
|
|
|
+Md5.buffer32Identity = new Int32Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
|
|
|
|
|
+Md5.hexChars = "0123456789abcdef";
|
|
|
|
|
+Md5.hexOut = [];
|
|
|
|
|
+Md5.onePassHasher = new Md5();
|
|
|
|
|
+if (Md5.hashStr("hello") !== "5d41402abc4b2a76b9719d911017c592") {
|
|
|
|
|
+ throw new Error("Md5 self test failed.");
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// src/utils.ts
|
|
|
|
|
+var PASTED_IMAGE_PREFIX = "Pasted image ";
|
|
|
|
|
+var ImageExtensionRegex = /^(jpe?g|png|gif|svg|bmp|eps|webp)$/i;
|
|
|
|
|
+function isMarkdownFile(extension) {
|
|
|
|
|
+ return extension === "md";
|
|
|
|
|
+}
|
|
|
|
|
+function isCanvasFile(extension) {
|
|
|
|
|
+ return extension === "canvas";
|
|
|
|
|
+}
|
|
|
|
|
+function isPastedImage(file) {
|
|
|
|
|
+ if (file instanceof import_obsidian2.TFile) {
|
|
|
|
|
+ if (file.name.startsWith(PASTED_IMAGE_PREFIX)) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return false;
|
|
|
|
|
+}
|
|
|
|
|
+function isImage(extension) {
|
|
|
|
|
+ const match = extension.match(ImageExtensionRegex);
|
|
|
|
|
+ if (match !== null) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ return false;
|
|
|
|
|
+}
|
|
|
|
|
+function stripPaths(src, dst) {
|
|
|
|
|
+ if (src === dst) {
|
|
|
|
|
+ return { stripedSrc: src, stripedDst: dst };
|
|
|
|
|
+ }
|
|
|
|
|
+ const srcParts = src.split("/");
|
|
|
|
|
+ const dstParts = dst.split("/");
|
|
|
|
|
+ if (srcParts.length !== dstParts.length) {
|
|
|
|
|
+ return { stripedSrc: src, stripedDst: dst };
|
|
|
|
|
+ }
|
|
|
|
|
+ for (let i = 0; i < srcParts.length; i++) {
|
|
|
|
|
+ const srcPart = srcParts[i];
|
|
|
|
|
+ const dstPart = dstParts[i];
|
|
|
|
|
+ if (srcPart !== dstPart) {
|
|
|
|
|
+ return {
|
|
|
|
|
+ stripedSrc: srcParts.slice(0, i + 1).join("/"),
|
|
|
|
|
+ stripedDst: dstParts.slice(0, i + 1).join("/")
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return { stripedSrc: "", stripedDst: "" };
|
|
|
|
|
+}
|
|
|
|
|
+function matchExtension(extension, pattern) {
|
|
|
|
|
+ if (!pattern || pattern === "") return false;
|
|
|
|
|
+ return new RegExp(pattern).test(extension);
|
|
|
|
|
+}
|
|
|
|
|
+function isAttachment(app2, settings, filePath) {
|
|
|
|
|
+ let file = null;
|
|
|
|
|
+ if (filePath instanceof import_obsidian2.TAbstractFile) {
|
|
|
|
|
+ file = filePath;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ file = app2.vault.getAbstractFileByPath(filePath);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (file === null || !(file instanceof import_obsidian2.TFile)) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (isMarkdownFile(file.extension) || isCanvasFile(file.extension)) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ return !matchExtension(file.extension, settings.excludeExtensionPattern);
|
|
|
|
|
+}
|
|
|
|
|
+async function md5sum(adapter, file) {
|
|
|
|
|
+ const md5 = new Md5();
|
|
|
|
|
+ if (!adapter.exists(file.path, true)) {
|
|
|
|
|
+ return "";
|
|
|
|
|
+ }
|
|
|
|
|
+ const content = await adapter.readBinary(file.path);
|
|
|
|
|
+ md5.appendByteArray(new Uint8Array(content));
|
|
|
|
|
+ const ret = md5.end();
|
|
|
|
|
+ return ret.toUpperCase();
|
|
|
|
|
+}
|
|
|
|
|
+function validateExtensionEntry(setting, plugin) {
|
|
|
|
|
+ const wrongIndex = [];
|
|
|
|
|
+ if (setting.extensionOverride !== void 0) {
|
|
|
|
|
+ const extOverride = setting.extensionOverride;
|
|
|
|
|
+ if (extOverride.some((ext) => ext.extension === "")) {
|
|
|
|
|
+ wrongIndex.push({ type: "empty", index: extOverride.findIndex((ext) => ext.extension === "") });
|
|
|
|
|
+ }
|
|
|
|
|
+ const duplicate = extOverride.map((ext) => ext.extension).filter((value, index, self) => self.indexOf(value) !== index);
|
|
|
|
|
+ if (duplicate.length > 0) {
|
|
|
|
|
+ duplicate.forEach((dupli) => {
|
|
|
|
|
+ wrongIndex.push({ type: "duplicate", index: extOverride.findIndex((ext) => dupli === ext.extension) });
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ const markdown = extOverride.filter((ext) => ext.extension === "md");
|
|
|
|
|
+ if (markdown.length > 0) {
|
|
|
|
|
+ wrongIndex.push({ type: "md", index: extOverride.findIndex((ext) => ext.extension === "md") });
|
|
|
|
|
+ }
|
|
|
|
|
+ const canvas = extOverride.filter((ext) => ext.extension === "canvas");
|
|
|
|
|
+ if (canvas.length > 0) {
|
|
|
|
|
+ wrongIndex.push({ type: "canvas", index: extOverride.findIndex((ext) => ext.extension === "canvas") });
|
|
|
|
|
+ }
|
|
|
|
|
+ const excludedFromSettings = plugin.excludeExtensionPattern.split("|");
|
|
|
|
|
+ const excluded = extOverride.filter((ext) => excludedFromSettings.includes(ext.extension));
|
|
|
|
|
+ if (excluded.length > 0) {
|
|
|
|
|
+ wrongIndex.push({
|
|
|
|
|
+ type: "excluded",
|
|
|
|
|
+ index: extOverride.findIndex((ext) => excludedFromSettings.includes(ext.extension))
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return wrongIndex;
|
|
|
|
|
+}
|
|
|
|
|
+function generateErrorExtensionMessage(type) {
|
|
|
|
|
+ if (type === "canvas") {
|
|
|
|
|
+ new import_obsidian2.Notice(t("errors.canvasNotSupported"));
|
|
|
|
|
+ } else if (type === "md") {
|
|
|
|
|
+ new import_obsidian2.Notice(t("errors.markdownNotSupported"));
|
|
|
|
|
+ } else if (type === "empty") {
|
|
|
|
|
+ new import_obsidian2.Notice(t("errors.extensionEmpty"));
|
|
|
|
|
+ } else if (type === "duplicate") {
|
|
|
|
|
+ new import_obsidian2.Notice(t("errors.duplicateExtension"));
|
|
|
|
|
+ } else if (type === "excluded") {
|
|
|
|
|
+ new import_obsidian2.Notice(t("errors.excludedExtension"));
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+var ALLOWED_FORMAT_VARS = [
|
|
|
|
|
+ SETTINGS_VARIABLES_DATES,
|
|
|
|
|
+ SETTINGS_VARIABLES_NOTENAME,
|
|
|
|
|
+ SETTINGS_VARIABLES_MD5,
|
|
|
|
|
+ SETTINGS_VARIABLES_ORIGINALNAME
|
|
|
|
|
+];
|
|
|
|
|
+var ILLEGAL_FILENAME_CHARS = /[\\/:*?"<>|]/;
|
|
|
|
|
+var VAR_TOKEN_RE = /\$\{[^}]+\}/g;
|
|
|
|
|
+function validateAttachFormat(value) {
|
|
|
|
|
+ var _a;
|
|
|
|
|
+ const trimmed = value.trim();
|
|
|
|
|
+ if (trimmed.length === 0) return { type: "empty" };
|
|
|
|
|
+ const stripped = trimmed.replace(VAR_TOKEN_RE, "");
|
|
|
|
|
+ const bad = stripped.match(ILLEGAL_FILENAME_CHARS);
|
|
|
|
|
+ if (bad) return { type: "illegalChar", char: bad[0] };
|
|
|
|
|
+ const vars = (_a = trimmed.match(VAR_TOKEN_RE)) != null ? _a : [];
|
|
|
|
|
+ for (const v of vars) {
|
|
|
|
|
+ if (!ALLOWED_FORMAT_VARS.includes(v)) {
|
|
|
|
|
+ return { type: "unknownVariable", name: v };
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return null;
|
|
|
|
|
+}
|
|
|
|
|
+function attachFormatErrorMessage(err) {
|
|
|
|
|
+ switch (err.type) {
|
|
|
|
|
+ case "empty":
|
|
|
|
|
+ return t("errors.attachFormatEmpty");
|
|
|
|
|
+ case "illegalChar":
|
|
|
|
|
+ return t("errors.attachFormatIllegalChar", { char: err.char });
|
|
|
|
|
+ case "unknownVariable":
|
|
|
|
|
+ return t("errors.attachFormatUnknownVariable", { name: err.name });
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+var ALLOWED_PATH_VARS = [SETTINGS_VARIABLES_NOTEPATH, SETTINGS_VARIABLES_NOTENAME, SETTINGS_VARIABLES_NOTEPARENT];
|
|
|
|
|
+var ILLEGAL_PATH_CHARS = /[\\:*?"<>|]/;
|
|
|
|
|
+function validateAttachmentPath(value) {
|
|
|
|
|
+ var _a;
|
|
|
|
|
+ const trimmed = value.trim();
|
|
|
|
|
+ if (trimmed.length === 0) return { type: "empty" };
|
|
|
|
|
+ const stripped = trimmed.replace(VAR_TOKEN_RE, "");
|
|
|
|
|
+ const bad = stripped.match(ILLEGAL_PATH_CHARS);
|
|
|
|
|
+ if (bad) return { type: "illegalChar", char: bad[0] };
|
|
|
|
|
+ const vars = (_a = trimmed.match(VAR_TOKEN_RE)) != null ? _a : [];
|
|
|
|
|
+ for (const v of vars) {
|
|
|
|
|
+ if (!ALLOWED_PATH_VARS.includes(v)) {
|
|
|
|
|
+ return { type: "unknownVariable", name: v };
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return null;
|
|
|
|
|
+}
|
|
|
|
|
+function attachmentPathErrorMessage(err) {
|
|
|
|
|
+ switch (err.type) {
|
|
|
|
|
+ case "empty":
|
|
|
|
|
+ return t("errors.attachmentPathEmpty");
|
|
|
|
|
+ case "illegalChar":
|
|
|
|
|
+ return t("errors.attachmentPathIllegalChar", { char: err.char });
|
|
|
|
|
+ case "unknownVariable":
|
|
|
|
|
+ return t("errors.attachmentPathUnknownVariable", { name: err.name });
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// src/lib/log.ts
|
|
|
|
|
+var DEBUG = false;
|
|
|
|
|
+if (DEBUG) console.log("DEBUG is enabled");
|
|
|
|
|
+function debugLog(...args) {
|
|
|
|
|
+ if (DEBUG) {
|
|
|
|
|
+ console.log((/* @__PURE__ */ new Date()).toISOString().slice(11, 23), ...args);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// src/model/extensionOverride.ts
|
|
|
|
|
+function getExtensionOverrideSetting(extension, settings) {
|
|
|
|
|
+ if (settings.extensionOverride === void 0 || settings.extensionOverride.length === 0) {
|
|
|
|
|
+ return { extSetting: void 0 };
|
|
|
|
|
+ }
|
|
|
|
|
+ for (let i = 0; i < settings.extensionOverride.length; i++) {
|
|
|
|
|
+ if (matchExtension(extension, settings.extensionOverride[i].extension)) {
|
|
|
|
|
+ debugLog(
|
|
|
|
|
+ "getExtensionOverrideSetting - ",
|
|
|
|
|
+ settings.extensionOverride[i].extension,
|
|
|
|
|
+ settings.extensionOverride[i]
|
|
|
|
|
+ );
|
|
|
|
|
+ return { extSetting: settings.extensionOverride[i] };
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return { extSetting: void 0 };
|
|
|
|
|
+}
|
|
|
|
|
+var OverrideExtensionModal = class extends import_obsidian3.Modal {
|
|
|
|
|
+ constructor(plugin, settings, onSubmit) {
|
|
|
|
|
+ super(plugin.app);
|
|
|
|
|
+ this.plugin = plugin;
|
|
|
|
|
+ this.settings = settings;
|
|
|
|
|
+ this.onSubmit = onSubmit;
|
|
|
|
|
+ }
|
|
|
|
|
+ displaySw(cont) {
|
|
|
|
|
+ cont.findAll(".setting-item").forEach((el) => {
|
|
|
|
|
+ var _a;
|
|
|
|
|
+ if ((_a = el.getAttr("class")) == null ? void 0 : _a.includes("override_root_folder_set")) {
|
|
|
|
|
+ if (this.settings.saveAttE === "obsFolder") {
|
|
|
|
|
+ el.hide();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ el.show();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ onOpen() {
|
|
|
|
|
+ const { contentEl } = this;
|
|
|
|
|
+ contentEl.empty();
|
|
|
|
|
+ contentEl.createEl("h3", {
|
|
|
|
|
+ text: t("extensionOverride.title")
|
|
|
|
|
+ });
|
|
|
|
|
+ new import_obsidian3.Setting(contentEl).setName(t("extensionOverride.rootPath.name")).setDesc(t("extensionOverride.rootPath.desc")).addDropdown(
|
|
|
|
|
+ (text) => text.addOption(`${SETTINGS_ROOT_OBSFOLDER}`, t("settings.rootPath.options.obsidian")).addOption(`${SETTINGS_ROOT_INFOLDER}`, t("settings.rootPath.options.inFolder")).addOption(`${SETTINGS_ROOT_NEXTTONOTE}`, t("settings.rootPath.options.nextToNote")).setValue(this.settings.saveAttE).onChange(async (value) => {
|
|
|
|
|
+ this.settings.saveAttE = value;
|
|
|
|
|
+ this.displaySw(contentEl);
|
|
|
|
|
+ this.onOpen();
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ if (this.settings.saveAttE !== "obsFolder") {
|
|
|
|
|
+ new import_obsidian3.Setting(contentEl).setName(t("extensionOverride.rootFolder.name")).setDesc(t("extensionOverride.rootFolder.desc")).setClass("override_root_folder_set").addText(
|
|
|
|
|
+ (text) => text.setPlaceholder(DEFAULT_SETTINGS.attachPath.attachmentRoot).setValue(this.settings.attachmentRoot).onChange(async (value) => {
|
|
|
|
|
+ this.settings.attachmentRoot = value;
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+ new import_obsidian3.Setting(contentEl).setName(t("extensionOverride.attachmentPath.name")).setDesc(t("extensionOverride.attachmentPath.desc")).addText(
|
|
|
|
|
+ (text) => text.setPlaceholder(DEFAULT_SETTINGS.attachPath.attachmentPath).setValue(this.settings.attachmentPath).onChange(async (value) => {
|
|
|
|
|
+ this.settings.attachmentPath = value;
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ new import_obsidian3.Setting(contentEl).setName(t("extensionOverride.attachmentFormat.name")).setDesc(t("extensionOverride.attachmentFormat.desc")).addText(
|
|
|
|
|
+ (text) => text.setPlaceholder(DEFAULT_SETTINGS.attachPath.attachFormat).setValue(this.settings.attachFormat).onChange(async (value) => {
|
|
|
|
|
+ this.settings.attachFormat = value;
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ new import_obsidian3.Setting(contentEl).addButton(
|
|
|
|
|
+ (button) => button.setButtonText(t("extensionOverride.buttons.save")).onClick(async () => {
|
|
|
|
|
+ this.onSubmit(this.settings);
|
|
|
|
|
+ this.close();
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+ onClose() {
|
|
|
|
|
+ const { contentEl } = this;
|
|
|
|
|
+ contentEl.empty();
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// src/settings/settings.ts
|
|
|
|
|
+var DEFAULT_SETTINGS = {
|
|
|
|
|
+ attachPath: {
|
|
|
|
|
+ attachmentRoot: "",
|
|
|
|
|
+ saveAttE: `${SETTINGS_ROOT_OBSFOLDER}`,
|
|
|
|
|
+ attachmentPath: `${SETTINGS_VARIABLES_NOTEPATH}/${SETTINGS_VARIABLES_NOTENAME}`,
|
|
|
|
|
+ attachFormat: `IMG-${SETTINGS_VARIABLES_DATES}`,
|
|
|
|
|
+ type: "GLOBAL" /* GLOBAL */
|
|
|
|
|
+ },
|
|
|
|
|
+ dateFormat: "YYYYMMDDHHmmssSSS",
|
|
|
|
|
+ excludeExtensionPattern: "",
|
|
|
|
|
+ autoRenameAttachment: true,
|
|
|
|
|
+ excludedPaths: "",
|
|
|
|
|
+ excludePathsArray: [],
|
|
|
|
|
+ excludeSubpaths: false,
|
|
|
|
|
+ originalNameStorage: [],
|
|
|
|
|
+ overridePath: {},
|
|
|
|
|
+ disableNotification: false
|
|
|
|
|
+};
|
|
|
|
|
+var AttachmentManagementSettingTab = class extends import_obsidian4.PluginSettingTab {
|
|
|
|
|
+ constructor(app2, plugin) {
|
|
|
|
|
+ super(app2, plugin);
|
|
|
|
|
+ this.plugin = plugin;
|
|
|
|
|
+ }
|
|
|
|
|
+ displaySw(cont) {
|
|
|
|
|
+ cont.findAll(".setting-item").forEach((el) => {
|
|
|
|
|
+ var _a;
|
|
|
|
|
+ if ((_a = el.getAttr("class")) == null ? void 0 : _a.includes("root_folder_set")) {
|
|
|
|
|
+ if (this.plugin.settings.attachPath.saveAttE === "obsFolder") {
|
|
|
|
|
+ el.hide();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ el.show();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ splitPath(path2) {
|
|
|
|
|
+ const splitted = path2.split(";");
|
|
|
|
|
+ const rets = [];
|
|
|
|
|
+ for (const s of splitted) {
|
|
|
|
|
+ rets.push(s.trim());
|
|
|
|
|
+ }
|
|
|
|
|
+ return { splittedPaths: rets };
|
|
|
|
|
+ }
|
|
|
|
|
+ display() {
|
|
|
|
|
+ const { containerEl } = this;
|
|
|
|
|
+ containerEl.empty();
|
|
|
|
|
+ containerEl.createEl("h2", { text: t("settings.title") });
|
|
|
|
|
+ new import_obsidian4.Setting(containerEl).setName(t("settings.rootPath.name")).setDesc(t("settings.rootPath.desc")).addDropdown(
|
|
|
|
|
+ (text) => text.addOption(`${SETTINGS_ROOT_OBSFOLDER}`, t("settings.rootPath.options.obsidian")).addOption(`${SETTINGS_ROOT_INFOLDER}`, t("settings.rootPath.options.inFolder")).addOption(`${SETTINGS_ROOT_NEXTTONOTE}`, t("settings.rootPath.options.nextToNote")).setValue(this.plugin.settings.attachPath.saveAttE).onChange(async (value) => {
|
|
|
|
|
+ this.plugin.settings.attachPath.saveAttE = value;
|
|
|
|
|
+ this.displaySw(containerEl);
|
|
|
|
|
+ await this.plugin.saveSettings();
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ new import_obsidian4.Setting(containerEl).setName(t("settings.rootFolder.name")).setDesc(t("settings.rootFolder.desc")).setClass("root_folder_set").addText(
|
|
|
|
|
+ (text) => text.setPlaceholder(DEFAULT_SETTINGS.attachPath.attachmentRoot).setValue(this.plugin.settings.attachPath.attachmentRoot).onChange(async (value) => {
|
|
|
|
|
+ debugLog("setting - attachment root:" + value);
|
|
|
|
|
+ this.plugin.settings.attachPath.attachmentRoot = value;
|
|
|
|
|
+ await this.plugin.saveSettings();
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ new import_obsidian4.Setting(containerEl).setName(t("settings.attachmentPath.name")).setDesc(t("settings.attachmentPath.desc")).addText((text) => {
|
|
|
|
|
+ const controlEl = text.inputEl.parentElement;
|
|
|
|
|
+ const errEl = controlEl.createDiv({ cls: "setting-item-description" });
|
|
|
|
|
+ controlEl.insertBefore(errEl, text.inputEl);
|
|
|
|
|
+ errEl.style.color = "var(--color-red)";
|
|
|
|
|
+ errEl.style.marginRight = "8px";
|
|
|
|
|
+ errEl.style.textAlign = "right";
|
|
|
|
|
+ errEl.hide();
|
|
|
|
|
+ const applyValidation = (value) => {
|
|
|
|
|
+ const err = validateAttachmentPath(value);
|
|
|
|
|
+ if (err) {
|
|
|
|
|
+ text.inputEl.style.border = "1px solid var(--color-red)";
|
|
|
|
|
+ errEl.setText(attachmentPathErrorMessage(err));
|
|
|
|
|
+ errEl.show();
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ text.inputEl.style.border = "";
|
|
|
|
|
+ errEl.hide();
|
|
|
|
|
+ return true;
|
|
|
|
|
+ };
|
|
|
|
|
+ text.setPlaceholder(DEFAULT_SETTINGS.attachPath.attachmentPath).setValue(this.plugin.settings.attachPath.attachmentPath).onChange(async (value) => {
|
|
|
|
|
+ debugLog("setting - attachment path:" + value);
|
|
|
|
|
+ if (!applyValidation(value)) return;
|
|
|
|
|
+ this.plugin.settings.attachPath.attachmentPath = value;
|
|
|
|
|
+ await this.plugin.saveSettings();
|
|
|
|
|
+ });
|
|
|
|
|
+ applyValidation(this.plugin.settings.attachPath.attachmentPath);
|
|
|
|
|
+ });
|
|
|
|
|
+ new import_obsidian4.Setting(containerEl).setName(t("settings.attachmentFormat.name")).setDesc(t("settings.attachmentFormat.desc")).addText((text) => {
|
|
|
|
|
+ const controlEl = text.inputEl.parentElement;
|
|
|
|
|
+ const errEl = controlEl.createDiv({ cls: "setting-item-description" });
|
|
|
|
|
+ controlEl.insertBefore(errEl, text.inputEl);
|
|
|
|
|
+ errEl.style.color = "var(--color-red)";
|
|
|
|
|
+ errEl.style.marginRight = "8px";
|
|
|
|
|
+ errEl.style.textAlign = "right";
|
|
|
|
|
+ errEl.hide();
|
|
|
|
|
+ const applyValidation = (value) => {
|
|
|
|
|
+ const err = validateAttachFormat(value);
|
|
|
|
|
+ if (err) {
|
|
|
|
|
+ text.inputEl.style.border = "1px solid var(--color-red)";
|
|
|
|
|
+ errEl.setText(attachFormatErrorMessage(err));
|
|
|
|
|
+ errEl.show();
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ text.inputEl.style.border = "";
|
|
|
|
|
+ errEl.hide();
|
|
|
|
|
+ return true;
|
|
|
|
|
+ };
|
|
|
|
|
+ text.setPlaceholder(DEFAULT_SETTINGS.attachPath.attachFormat).setValue(this.plugin.settings.attachPath.attachFormat).onChange(async (value) => {
|
|
|
|
|
+ debugLog("setting - attachment format:" + value);
|
|
|
|
|
+ if (!applyValidation(value)) return;
|
|
|
|
|
+ this.plugin.settings.attachPath.attachFormat = value;
|
|
|
|
|
+ await this.plugin.saveSettings();
|
|
|
|
|
+ });
|
|
|
|
|
+ applyValidation(this.plugin.settings.attachPath.attachFormat);
|
|
|
|
|
+ });
|
|
|
|
|
+ new import_obsidian4.Setting(containerEl).setName(t("settings.dateFormat.name")).setDesc(
|
|
|
|
|
+ createFragment((frag) => {
|
|
|
|
|
+ frag.appendText(t("settings.dateFormat.desc") + " ");
|
|
|
|
|
+ frag.createEl("a", {
|
|
|
|
|
+ href: "https://momentjscom.readthedocs.io/en/latest/moment/04-displaying/01-format",
|
|
|
|
|
+ text: t("settings.dateFormat.linkText")
|
|
|
|
|
+ });
|
|
|
|
|
+ })
|
|
|
|
|
+ ).addMomentFormat((component) => {
|
|
|
|
|
+ component.setPlaceholder(DEFAULT_SETTINGS.dateFormat).setValue(this.plugin.settings.dateFormat).onChange(async (value) => {
|
|
|
|
|
+ debugLog("setting - date format:" + value);
|
|
|
|
|
+ this.plugin.settings.dateFormat = value;
|
|
|
|
|
+ await this.plugin.saveSettings();
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ new import_obsidian4.Setting(containerEl).setName(t("settings.autoRename.name")).setDesc(t("settings.autoRename.desc")).addToggle(
|
|
|
|
|
+ (toggle) => toggle.setValue(this.plugin.settings.autoRenameAttachment).onChange(async (value) => {
|
|
|
|
|
+ debugLog("setting - automatically rename attachment folder:" + value);
|
|
|
|
|
+ this.plugin.settings.autoRenameAttachment = value;
|
|
|
|
|
+ await this.plugin.saveSettings();
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ new import_obsidian4.Setting(containerEl).setName(t("settings.extensionOverride.name")).setDesc(t("settings.extensionOverride.desc")).addButton((btn) => {
|
|
|
|
|
+ btn.setButtonText(t("settings.extensionOverride.addButton")).onClick(async () => {
|
|
|
|
|
+ if (this.plugin.settings.attachPath.extensionOverride === void 0) {
|
|
|
|
|
+ this.plugin.settings.attachPath.extensionOverride = [];
|
|
|
|
|
+ }
|
|
|
|
|
+ this.plugin.settings.attachPath.extensionOverride.push({
|
|
|
|
|
+ extension: "",
|
|
|
|
|
+ attachmentRoot: this.plugin.settings.attachPath.attachmentRoot,
|
|
|
|
|
+ saveAttE: this.plugin.settings.attachPath.saveAttE,
|
|
|
|
|
+ attachmentPath: this.plugin.settings.attachPath.attachmentPath,
|
|
|
|
|
+ attachFormat: this.plugin.settings.attachPath.attachFormat
|
|
|
|
|
+ });
|
|
|
|
|
+ await this.plugin.saveSettings();
|
|
|
|
|
+ this.display();
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ if (this.plugin.settings.attachPath.extensionOverride !== void 0) {
|
|
|
|
|
+ this.plugin.settings.attachPath.extensionOverride.forEach((ext) => {
|
|
|
|
|
+ new import_obsidian4.Setting(containerEl).setName(t("settings.extensionOverride.extension.name")).setDesc(t("settings.extensionOverride.extension.desc")).setClass("override_extension_set").addText(
|
|
|
|
|
+ (text) => text.setPlaceholder(t("settings.extensionOverride.extension.placeholder")).setValue(ext.extension).onChange(async (value) => {
|
|
|
|
|
+ ext.extension = value;
|
|
|
|
|
+ })
|
|
|
|
|
+ ).addButton((btn) => {
|
|
|
|
|
+ btn.setIcon("trash").setTooltip(t("settings.extensionOverride.tooltips.remove")).onClick(async () => {
|
|
|
|
|
+ var _a, _b, _c;
|
|
|
|
|
+ const index = (_b = (_a = this.plugin.settings.attachPath.extensionOverride) == null ? void 0 : _a.indexOf(ext)) != null ? _b : -1;
|
|
|
|
|
+ (_c = this.plugin.settings.attachPath.extensionOverride) == null ? void 0 : _c.splice(index, 1);
|
|
|
|
|
+ await this.plugin.saveSettings();
|
|
|
|
|
+ this.display();
|
|
|
|
|
+ });
|
|
|
|
|
+ }).addButton((btn) => {
|
|
|
|
|
+ btn.setIcon("pencil").setTooltip(t("settings.extensionOverride.tooltips.edit")).onClick(async () => {
|
|
|
|
|
+ new OverrideExtensionModal(this.plugin, ext, (result) => {
|
|
|
|
|
+ ext = result;
|
|
|
|
|
+ }).open();
|
|
|
|
|
+ });
|
|
|
|
|
+ }).addButton((btn) => {
|
|
|
|
|
+ btn.setIcon("check").setTooltip(t("settings.extensionOverride.tooltips.save")).onClick(async () => {
|
|
|
|
|
+ const wrongIndex = validateExtensionEntry(this.plugin.settings.attachPath, this.plugin.settings);
|
|
|
|
|
+ if (wrongIndex.length > 0) {
|
|
|
|
|
+ for (const i of wrongIndex) {
|
|
|
|
|
+ const resIndex = i.index < 0 ? 0 : i.index;
|
|
|
|
|
+ const wrongSetting = containerEl.getElementsByClassName("override_extension_set")[resIndex];
|
|
|
|
|
+ wrongSetting.getElementsByTagName("input")[0].style.border = "1px solid var(--color-red)";
|
|
|
|
|
+ generateErrorExtensionMessage(i.type);
|
|
|
|
|
+ }
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ await this.plugin.saveSettings();
|
|
|
|
|
+ this.display();
|
|
|
|
|
+ new import_obsidian4.Notice(t("settings.extensionOverride.saveNotice"));
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ new import_obsidian4.Setting(containerEl).setName(t("settings.excludeExtension.name")).setDesc(t("settings.excludeExtension.desc")).addText(
|
|
|
|
|
+ (text) => text.setPlaceholder(t("settings.excludeExtension.placeholder")).setValue(this.plugin.settings.excludeExtensionPattern).onChange(async (value) => {
|
|
|
|
|
+ this.plugin.settings.excludeExtensionPattern = value;
|
|
|
|
|
+ await this.plugin.saveSettings();
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ new import_obsidian4.Setting(containerEl).setName(t("settings.excludedPaths.name")).setDesc(t("settings.excludedPaths.desc")).addTextArea((component) => {
|
|
|
|
|
+ component.setValue(this.plugin.settings.excludedPaths).onChange(async (value) => {
|
|
|
|
|
+ this.plugin.settings.excludedPaths = value;
|
|
|
|
|
+ const { splittedPaths } = this.splitPath(value);
|
|
|
|
|
+ this.plugin.settings.excludePathsArray = splittedPaths;
|
|
|
|
|
+ debugLog("setting - excluded paths:" + value, splittedPaths);
|
|
|
|
|
+ await this.plugin.saveSettings();
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ new import_obsidian4.Setting(containerEl).setName(t("settings.excludeSubpaths.name")).setDesc(t("settings.excludeSubpaths.desc")).addToggle(
|
|
|
|
|
+ (toggle) => toggle.setValue(this.plugin.settings.excludeSubpaths).onChange(async (value) => {
|
|
|
|
|
+ debugLog("setting - excluded subpaths:" + value);
|
|
|
|
|
+ this.plugin.settings.excludeSubpaths = value;
|
|
|
|
|
+ await this.plugin.saveSettings();
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ this.displaySw(containerEl);
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// src/model/override.ts
|
|
|
|
|
+var import_obsidian5 = require("obsidian");
|
|
|
|
|
+var OverrideModal = class extends import_obsidian5.Modal {
|
|
|
|
|
+ constructor(plugin, file, setting) {
|
|
|
|
|
+ super(plugin.app);
|
|
|
|
|
+ this.plugin = plugin;
|
|
|
|
|
+ this.file = file;
|
|
|
|
|
+ this.setting = setting;
|
|
|
|
|
+ }
|
|
|
|
|
+ displaySw(cont) {
|
|
|
|
|
+ cont.findAll(".setting-item").forEach((el) => {
|
|
|
|
|
+ var _a;
|
|
|
|
|
+ if ((_a = el.getAttr("class")) == null ? void 0 : _a.includes("override_root_folder_set")) {
|
|
|
|
|
+ if (this.setting.saveAttE === "obsFolder") {
|
|
|
|
|
+ el.hide();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ el.show();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ onOpen() {
|
|
|
|
|
+ const { contentEl } = this;
|
|
|
|
|
+ contentEl.empty();
|
|
|
|
|
+ contentEl.createEl("h3", {
|
|
|
|
|
+ text: t("override.title")
|
|
|
|
|
+ });
|
|
|
|
|
+ new import_obsidian5.Setting(contentEl).setName(t("settings.rootPath.name")).setDesc(t("settings.rootPath.desc")).addDropdown(
|
|
|
|
|
+ (text) => text.addOption(`${SETTINGS_ROOT_OBSFOLDER}`, t("settings.rootPath.options.obsidian")).addOption(`${SETTINGS_ROOT_INFOLDER}`, t("settings.rootPath.options.inFolder")).addOption(`${SETTINGS_ROOT_NEXTTONOTE}`, t("settings.rootPath.options.nextToNote")).setValue(this.setting.saveAttE).onChange(async (value) => {
|
|
|
|
|
+ this.setting.saveAttE = value;
|
|
|
|
|
+ this.displaySw(contentEl);
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ new import_obsidian5.Setting(contentEl).setName(t("settings.rootFolder.name")).setDesc(t("settings.rootFolder.desc")).setClass("override_root_folder_set").addText(
|
|
|
|
|
+ (text) => text.setPlaceholder(DEFAULT_SETTINGS.attachPath.attachmentRoot).setValue(this.setting.attachmentRoot).onChange(async (value) => {
|
|
|
|
|
+ debugLog("override - attachment root:" + value);
|
|
|
|
|
+ this.setting.attachmentRoot = value;
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ new import_obsidian5.Setting(contentEl).setName(t("settings.attachmentPath.name")).setDesc(t("settings.attachmentPath.desc")).addText(
|
|
|
|
|
+ (text) => text.setPlaceholder(DEFAULT_SETTINGS.attachPath.attachmentPath).setValue(this.setting.attachmentPath).onChange(async (value) => {
|
|
|
|
|
+ debugLog("override - attachment path:" + value);
|
|
|
|
|
+ this.setting.attachmentPath = value;
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ new import_obsidian5.Setting(contentEl).setName(t("settings.attachmentFormat.name")).setDesc(t("settings.attachmentFormat.desc")).addText(
|
|
|
|
|
+ (text) => text.setPlaceholder(DEFAULT_SETTINGS.attachPath.attachFormat).setValue(this.setting.attachFormat).onChange(async (value) => {
|
|
|
|
|
+ debugLog("override - attachment format:" + value);
|
|
|
|
|
+ this.setting.attachFormat = value;
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ new import_obsidian5.Setting(contentEl).addButton((btn) => {
|
|
|
|
|
+ btn.setButtonText(t("override.addExtensionOverrides")).onClick(async () => {
|
|
|
|
|
+ if (this.setting.extensionOverride === void 0) {
|
|
|
|
|
+ this.setting.extensionOverride = [];
|
|
|
|
|
+ }
|
|
|
|
|
+ this.setting.extensionOverride.push({
|
|
|
|
|
+ extension: "",
|
|
|
|
|
+ saveAttE: this.setting.saveAttE,
|
|
|
|
|
+ attachmentRoot: this.setting.attachmentRoot,
|
|
|
|
|
+ attachmentPath: this.setting.attachmentPath,
|
|
|
|
|
+ attachFormat: this.setting.attachFormat
|
|
|
|
|
+ });
|
|
|
|
|
+ this.onOpen();
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ if (this.setting.extensionOverride !== void 0) {
|
|
|
|
|
+ this.setting.extensionOverride.forEach((ext) => {
|
|
|
|
|
+ new import_obsidian5.Setting(contentEl).setName(t("override.extension.name")).setDesc(t("override.extension.desc")).setClass("override_extension_set").addText(
|
|
|
|
|
+ (text) => text.setPlaceholder(t("override.extension.placeholder")).setValue(ext.extension).onChange(async (value) => {
|
|
|
|
|
+ ext.extension = value;
|
|
|
|
|
+ })
|
|
|
|
|
+ ).addButton((btn) => {
|
|
|
|
|
+ btn.setIcon("trash").onClick(async () => {
|
|
|
|
|
+ var _a, _b, _c;
|
|
|
|
|
+ const index = (_b = (_a = this.setting.extensionOverride) == null ? void 0 : _a.indexOf(ext)) != null ? _b : -1;
|
|
|
|
|
+ (_c = this.setting.extensionOverride) == null ? void 0 : _c.splice(index, 1);
|
|
|
|
|
+ this.onOpen();
|
|
|
|
|
+ });
|
|
|
|
|
+ }).addButton((btn) => {
|
|
|
|
|
+ btn.setIcon("pencil").onClick(async () => {
|
|
|
|
|
+ new OverrideExtensionModal(this.plugin, ext, (result) => {
|
|
|
|
|
+ ext = result;
|
|
|
|
|
+ }).open();
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ new import_obsidian5.Setting(contentEl).addButton((btn) => {
|
|
|
|
|
+ btn.setButtonText(t("override.buttons.reset")).onClick(async () => {
|
|
|
|
|
+ this.setting = this.plugin.settings.attachPath;
|
|
|
|
|
+ delete this.plugin.settings.overridePath[this.file.path];
|
|
|
|
|
+ await this.plugin.saveSettings();
|
|
|
|
|
+ await this.plugin.loadSettings();
|
|
|
|
|
+ new import_obsidian5.Notice(t("override.notifications.reset", { path: this.file.path }));
|
|
|
|
|
+ this.close();
|
|
|
|
|
+ });
|
|
|
|
|
+ }).addButton(
|
|
|
|
|
+ (btn) => btn.setButtonText(t("override.buttons.submit")).setCta().onClick(async () => {
|
|
|
|
|
+ if (this.file instanceof import_obsidian5.TFile) {
|
|
|
|
|
+ this.setting.type = "FILE" /* FILE */;
|
|
|
|
|
+ } else if (this.file instanceof import_obsidian5.TFolder) {
|
|
|
|
|
+ this.setting.type = "FOLDER" /* FOLDER */;
|
|
|
|
|
+ }
|
|
|
|
|
+ this.plugin.settings.overridePath[this.file.path] = this.setting;
|
|
|
|
|
+ await this.plugin.saveSettings();
|
|
|
|
|
+ debugLog("override - overriding settings:", this.file.path, this.setting);
|
|
|
|
|
+ new import_obsidian5.Notice(t("override.notifications.overridden", { path: this.file.path }));
|
|
|
|
|
+ this.close();
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ this.displaySw(contentEl);
|
|
|
|
|
+ }
|
|
|
|
|
+ onClose() {
|
|
|
|
|
+ const { contentEl } = this;
|
|
|
|
|
+ contentEl.empty();
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// src/model/confirm.ts
|
|
|
|
|
+var import_obsidian10 = require("obsidian");
|
|
|
|
|
+
|
|
|
|
|
+// src/arrange.ts
|
|
|
|
|
+var import_obsidian9 = require("obsidian");
|
|
|
|
|
+
|
|
|
|
|
+// src/lib/path.ts
|
|
|
|
|
+var path = {
|
|
|
|
|
+ // Credit: [@creationix/path.js](https://gist.github.com/creationix/7435851)
|
|
|
|
|
+ join(...partSegments) {
|
|
|
|
|
+ let parts = [];
|
|
|
|
|
+ for (let i = 0, l = partSegments.length; i < l; i++) {
|
|
|
|
|
+ parts = parts.concat(partSegments[i].split("/"));
|
|
|
|
|
+ }
|
|
|
|
|
+ const newParts = [];
|
|
|
|
|
+ for (let i = 0, l = parts.length; i < l; i++) {
|
|
|
|
|
+ const part = parts[i];
|
|
|
|
|
+ if (!part || part === ".") continue;
|
|
|
|
|
+ if (part === "..") newParts.pop();
|
|
|
|
|
+ else newParts.push(part);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (parts[0] === "") newParts.unshift("");
|
|
|
|
|
+ return newParts.join("/");
|
|
|
|
|
+ },
|
|
|
|
|
+ // A simple function to get the dirname of a path
|
|
|
|
|
+ // Trailing slashes are ignored. Leading slash is preserved.
|
|
|
|
|
+ dirname(filepath) {
|
|
|
|
|
+ return this.join(filepath, "..");
|
|
|
|
|
+ },
|
|
|
|
|
+ // returns the last part of a path, e.g. 'foo.jpg'
|
|
|
|
|
+ basename(filepath, extension = "") {
|
|
|
|
|
+ const sp = filepath.split("/");
|
|
|
|
|
+ const filename = sp[sp.length - 1];
|
|
|
|
|
+ if (extension !== "") {
|
|
|
|
|
+ return filename.slice(0, filename.length - extension.length - 1);
|
|
|
|
|
+ }
|
|
|
|
|
+ return sp[sp.length - 1];
|
|
|
|
|
+ },
|
|
|
|
|
+ // return extension without dot, e.g. 'jpg'
|
|
|
|
|
+ extname(filepath) {
|
|
|
|
|
+ const positions = [...filepath.matchAll(new RegExp("\\.", "gi"))].map((a) => a.index);
|
|
|
|
|
+ const idx = positions[positions.length - 1];
|
|
|
|
|
+ if (idx === void 0) {
|
|
|
|
|
+ return "";
|
|
|
|
|
+ }
|
|
|
|
|
+ return filepath.slice(idx + 1);
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// src/override.ts
|
|
|
|
|
+var import_obsidian6 = require("obsidian");
|
|
|
|
|
+function getOverrideSetting(settings, file, oldPath = "") {
|
|
|
|
|
+ if (Object.keys(settings.overridePath).length === 0) {
|
|
|
|
|
+ return { settingPath: "", setting: settings.attachPath };
|
|
|
|
|
+ }
|
|
|
|
|
+ const candidates = {};
|
|
|
|
|
+ let fileType;
|
|
|
|
|
+ let filePath;
|
|
|
|
|
+ fileType = file instanceof import_obsidian6.TFile;
|
|
|
|
|
+ fileType = !(file instanceof import_obsidian6.TFolder);
|
|
|
|
|
+ if (oldPath === "") {
|
|
|
|
|
+ filePath = file.path;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ filePath = oldPath;
|
|
|
|
|
+ }
|
|
|
|
|
+ for (const overridePath of Object.keys(settings.overridePath)) {
|
|
|
|
|
+ const overrideSetting = settings.overridePath[overridePath];
|
|
|
|
|
+ if (fileType) {
|
|
|
|
|
+ if (overridePath === filePath && overrideSetting.type === "FILE" /* FILE */) {
|
|
|
|
|
+ return { settingPath: overridePath, setting: overrideSetting };
|
|
|
|
|
+ } else if (filePath.startsWith(overridePath) && filePath.charAt(overridePath.length) === "/" && overrideSetting.type === "FOLDER" /* FOLDER */) {
|
|
|
|
|
+ candidates[overridePath] = overrideSetting;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (overridePath === filePath && overrideSetting.type === "FOLDER" /* FOLDER */) {
|
|
|
|
|
+ return { settingPath: overridePath, setting: overrideSetting };
|
|
|
|
|
+ } else if (filePath.startsWith(overridePath) && filePath.charAt(overridePath.length) === "/" && overrideSetting.type === "FOLDER" /* FOLDER */) {
|
|
|
|
|
+ candidates[overridePath] = overrideSetting;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (Object.keys(candidates).length === 0) {
|
|
|
|
|
+ return { settingPath: "", setting: settings.attachPath };
|
|
|
|
|
+ }
|
|
|
|
|
+ const sortedK = Object.keys(candidates).sort(
|
|
|
|
|
+ (a, b) => a.split("/").length > b.split("/").length ? -1 : a.split("/").length < b.split("/").length ? 1 : 0
|
|
|
|
|
+ );
|
|
|
|
|
+ debugLog("getOverrideSetting - sortedK:", sortedK);
|
|
|
|
|
+ for (const k of sortedK) {
|
|
|
|
|
+ if (filePath.startsWith(k)) {
|
|
|
|
|
+ return { settingPath: k, setting: candidates[k] };
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return { settingPath: "", setting: settings.attachPath };
|
|
|
|
|
+}
|
|
|
|
|
+function getRenameOverrideSetting(settings, file, oldPath) {
|
|
|
|
|
+ if (Object.keys(settings.overridePath).length === 0) {
|
|
|
|
|
+ return { settingPath: "", setting: settings.attachPath };
|
|
|
|
|
+ }
|
|
|
|
|
+ const { settingPath: np, setting: ns } = getOverrideSetting(settings, file);
|
|
|
|
|
+ const { settingPath: op, setting: os } = getOverrideSetting(settings, file, oldPath);
|
|
|
|
|
+ if (ns.type === "GLOBAL" /* GLOBAL */) {
|
|
|
|
|
+ return { settingPath: op, setting: os };
|
|
|
|
|
+ }
|
|
|
|
|
+ if (os.type === "GLOBAL" /* GLOBAL */) {
|
|
|
|
|
+ return { settingPath: np, setting: ns };
|
|
|
|
|
+ }
|
|
|
|
|
+ if (ns.type === "FILE" /* FILE */ && os.type === "FILE" /* FILE */) {
|
|
|
|
|
+ debugLog("getRenameOverrideSetting - both file type setting", np, op);
|
|
|
|
|
+ return { settingPath: "", setting: settings.attachPath };
|
|
|
|
|
+ }
|
|
|
|
|
+ if (ns.type === "FILE" /* FILE */ && os.type === "FOLDER" /* FOLDER */) {
|
|
|
|
|
+ return { settingPath: np, setting: ns };
|
|
|
|
|
+ } else if (ns.type === "FOLDER" /* FOLDER */ && os.type === "FILE" /* FILE */) {
|
|
|
|
|
+ return { settingPath: op, setting: os };
|
|
|
|
|
+ }
|
|
|
|
|
+ if (ns.type === "FOLDER" /* FOLDER */ && os.type === "FOLDER" /* FOLDER */) {
|
|
|
|
|
+ const l = np.split("/").length;
|
|
|
|
|
+ const r = op.split("/").length;
|
|
|
|
|
+ if (l > r) {
|
|
|
|
|
+ return { settingPath: np, setting: ns };
|
|
|
|
|
+ } else if (l < r) {
|
|
|
|
|
+ return { settingPath: op, setting: os };
|
|
|
|
|
+ } else if (l === r) {
|
|
|
|
|
+ return { settingPath: "", setting: os };
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return { settingPath: "", setting: settings.attachPath };
|
|
|
|
|
+}
|
|
|
|
|
+function updateOverrideSetting(settings, file, oldPath) {
|
|
|
|
|
+ const keys = Object.keys(settings.overridePath);
|
|
|
|
|
+ if (keys.length === 0 || file.path === oldPath) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ const { settingPath, setting } = getOverrideSetting(settings, file, oldPath);
|
|
|
|
|
+ const copySetting = Object.assign({}, setting);
|
|
|
|
|
+ if (file.path === settingPath) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (oldPath === settingPath) {
|
|
|
|
|
+ settings.overridePath[file.path] = copySetting;
|
|
|
|
|
+ delete settings.overridePath[settingPath];
|
|
|
|
|
+ return;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ const { stripedSrc, stripedDst } = stripPaths(oldPath, file.path);
|
|
|
|
|
+ if (stripedSrc === settingPath) {
|
|
|
|
|
+ settings.overridePath[stripedDst] = copySetting;
|
|
|
|
|
+ delete settings.overridePath[settingPath];
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+function deleteOverrideSetting(settings, file) {
|
|
|
|
|
+ const keys = Object.keys(settings.overridePath);
|
|
|
|
|
+ for (const key of keys) {
|
|
|
|
|
+ if (file.path === key) {
|
|
|
|
|
+ delete settings.overridePath[key];
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return false;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// src/lib/deduplicate.ts
|
|
|
|
|
+function escapeRegExp(s) {
|
|
|
|
|
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
|
|
|
+}
|
|
|
|
|
+async function deduplicateNewName(newName, file) {
|
|
|
|
|
+ const dir = file.path;
|
|
|
|
|
+ const listed = await file.vault.adapter.list(dir);
|
|
|
|
|
+ debugLog("deduplicateNewName - sibling files", listed);
|
|
|
|
|
+ const newNameExt = path.extname(newName), newNameStem = newName.slice(0, newName.length - newNameExt.length - 1), newNameStemEscaped = escapeRegExp(newNameStem), delimiter = "-", delimiterEscaped = escapeRegExp(delimiter);
|
|
|
|
|
+ const dupNameRegex = new RegExp(
|
|
|
|
|
+ `^(?<name>${newNameStemEscaped})${delimiterEscaped}(?<number>\\d{1,3})\\.${newNameExt}$`
|
|
|
|
|
+ );
|
|
|
|
|
+ debugLog("dupNameRegex", dupNameRegex);
|
|
|
|
|
+ const dupNameNumbers = [];
|
|
|
|
|
+ let isNewNameExist = false;
|
|
|
|
|
+ for (let sibling of listed.files) {
|
|
|
|
|
+ sibling = path.basename(sibling);
|
|
|
|
|
+ if (sibling == newName) {
|
|
|
|
|
+ isNewNameExist = true;
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ const m = dupNameRegex.exec(sibling);
|
|
|
|
|
+ if (!m || m.groups === void 0) continue;
|
|
|
|
|
+ dupNameNumbers.push(parseInt(m.groups.number));
|
|
|
|
|
+ }
|
|
|
|
|
+ if (isNewNameExist) {
|
|
|
|
|
+ const newNumber = dupNameNumbers.length > 0 ? Math.max(...dupNameNumbers) + 1 : 1;
|
|
|
|
|
+ newName = `${newNameStem}${delimiter}${newNumber}.${newNameExt}`;
|
|
|
|
|
+ }
|
|
|
|
|
+ return {
|
|
|
|
|
+ name: newName,
|
|
|
|
|
+ basename: newName.slice(0, newName.length - newNameExt.length - 1),
|
|
|
|
|
+ extension: newNameExt
|
|
|
|
|
+ };
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// src/settings/metadata.ts
|
|
|
|
|
+var import_obsidian8 = require("obsidian");
|
|
|
|
|
+
|
|
|
|
|
+// src/commons.ts
|
|
|
|
|
+var import_obsidian7 = require("obsidian");
|
|
|
|
|
+function getActiveFile(app2) {
|
|
|
|
|
+ const view = getActiveView(app2);
|
|
|
|
|
+ if (view == null) {
|
|
|
|
|
+ return void 0;
|
|
|
|
|
+ } else if (view.file == null) {
|
|
|
|
|
+ return void 0;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return view.file;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+function getActiveView(app2) {
|
|
|
|
|
+ return app2.workspace.getActiveViewOfType(import_obsidian7.TextFileView);
|
|
|
|
|
+}
|
|
|
|
|
+function getRootPath(notePath, setting) {
|
|
|
|
|
+ let root;
|
|
|
|
|
+ const obsmediadir = app.vault.getConfig("attachmentFolderPath");
|
|
|
|
|
+ switch (setting.saveAttE) {
|
|
|
|
|
+ case `${SETTINGS_ROOT_INFOLDER}`:
|
|
|
|
|
+ root = path.join(setting.attachmentRoot);
|
|
|
|
|
+ break;
|
|
|
|
|
+ case `${SETTINGS_ROOT_NEXTTONOTE}`:
|
|
|
|
|
+ root = path.join(notePath, setting.attachmentRoot.replace("./", ""));
|
|
|
|
|
+ break;
|
|
|
|
|
+ default:
|
|
|
|
|
+ if (obsmediadir === "/") {
|
|
|
|
|
+ root = obsmediadir;
|
|
|
|
|
+ } else if (obsmediadir === "./") {
|
|
|
|
|
+ root = path.join(notePath);
|
|
|
|
|
+ } else if (obsmediadir.match(/\.\/.+/g) !== null) {
|
|
|
|
|
+ root = path.join(notePath, obsmediadir.replace("./", ""));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ root = obsmediadir;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return root === "/" ? root : (0, import_obsidian7.normalizePath)(root);
|
|
|
|
|
+}
|
|
|
|
|
+async function checkEmptyFolder(adapter, path2) {
|
|
|
|
|
+ const exist = await adapter.exists(path2, true);
|
|
|
|
|
+ if (!exist) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ const data = await adapter.list(path2);
|
|
|
|
|
+ if (data.files.length > 0) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (data.folders.length > 0) {
|
|
|
|
|
+ for (let i = 0; i < data.folders.length; i++) {
|
|
|
|
|
+ return checkEmptyFolder(adapter, data.folders[i]);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return true;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// src/lib/originalStorage.ts
|
|
|
|
|
+function containsOriginalNameVariable(setting, ext) {
|
|
|
|
|
+ const { extSetting } = getExtensionOverrideSetting(ext, setting);
|
|
|
|
|
+ if (extSetting !== void 0) {
|
|
|
|
|
+ return extSetting.attachFormat.includes(SETTINGS_VARIABLES_ORIGINALNAME);
|
|
|
|
|
+ }
|
|
|
|
|
+ return setting.attachFormat.includes(SETTINGS_VARIABLES_ORIGINALNAME);
|
|
|
|
|
+}
|
|
|
|
|
+function saveOriginalName(settings, setting, ext, data) {
|
|
|
|
|
+ if (settings.originalNameStorage === void 0) {
|
|
|
|
|
+ settings.originalNameStorage = [];
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!containsOriginalNameVariable(setting, ext)) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ settings.originalNameStorage.filter((n) => n.md5 === data.md5).forEach((n) => settings.originalNameStorage.remove(n));
|
|
|
|
|
+ settings.originalNameStorage.push(data);
|
|
|
|
|
+}
|
|
|
|
|
+function loadOriginalName(settings, setting, ext, md5) {
|
|
|
|
|
+ if (!containsOriginalNameVariable(setting, ext)) {
|
|
|
|
|
+ return void 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ return settings.originalNameStorage.find((data) => data.md5 === md5);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// src/settings/metadata.ts
|
|
|
|
|
+var Metadata = class {
|
|
|
|
|
+ constructor(path2, name, basename, extension, parentPath, parentName, attachmentFile) {
|
|
|
|
|
+ /** parent path of file */
|
|
|
|
|
+ this.parentPath = "";
|
|
|
|
|
+ /** parent path basename of file */
|
|
|
|
|
+ this.parentName = "";
|
|
|
|
|
+ this.path = path2;
|
|
|
|
|
+ this.name = name;
|
|
|
|
|
+ this.basename = basename;
|
|
|
|
|
+ this.extension = extension;
|
|
|
|
|
+ this.parentPath = parentPath;
|
|
|
|
|
+ this.parentName = parentName;
|
|
|
|
|
+ this.attachmentFile = attachmentFile;
|
|
|
|
|
+ }
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns a formatted attachment file name according to the provided settings.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param {AttachmentPathSettings} setting - attachment path settings object
|
|
|
|
|
+ * @param {string} dateFormat - format string for date and time
|
|
|
|
|
+ * @param {TFile} originalAttach - the original attachment file
|
|
|
|
|
+ * @param {DataAdapter} adapter - vault adapter (used for md5 hashing)
|
|
|
|
|
+ * @param {AttachmentManagementPluginSettings} [pluginSettings] - plugin settings; when provided
|
|
|
|
|
+ * enables ${originalname} lookup from the persisted storage so the original
|
|
|
|
|
+ * name survives subsequent renames (e.g. rearrange).
|
|
|
|
|
+ * @return {string} the formatted attachment file name
|
|
|
|
|
+ */
|
|
|
|
|
+ async getAttachFileName(setting, dateFormat, originalAttach, adapter, pluginSettings) {
|
|
|
|
|
+ const dateTime = window.moment(originalAttach.stat.ctime).format(dateFormat);
|
|
|
|
|
+ let md5 = "";
|
|
|
|
|
+ let attachFormat = DEFAULT_SETTINGS.attachPath.attachFormat;
|
|
|
|
|
+ if (this.attachmentFile !== void 0) {
|
|
|
|
|
+ md5 = await md5sum(adapter, this.attachmentFile);
|
|
|
|
|
+ const { extSetting } = getExtensionOverrideSetting(this.attachmentFile.extension, setting);
|
|
|
|
|
+ if (extSetting !== void 0) {
|
|
|
|
|
+ attachFormat = extSetting.attachFormat;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ attachFormat = setting.attachFormat;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ let originalName = originalAttach.basename;
|
|
|
|
|
+ if (pluginSettings !== void 0 && this.attachmentFile !== void 0) {
|
|
|
|
|
+ const stored = loadOriginalName(pluginSettings, setting, this.attachmentFile.extension, md5);
|
|
|
|
|
+ if (stored !== void 0) {
|
|
|
|
|
+ originalName = stored.n;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return attachFormat.replace(`${SETTINGS_VARIABLES_DATES}`, dateTime).replace(`${SETTINGS_VARIABLES_NOTENAME}`, this.basename).replace(`${SETTINGS_VARIABLES_MD5}`, md5).replace(`${SETTINGS_VARIABLES_ORIGINALNAME}`, originalName);
|
|
|
|
|
+ }
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns the attachment path based on the given AttachmentPathSettings object.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param {AttachmentPathSettings} setting - An object containing the attachment path settings.
|
|
|
|
|
+ * @return {string} The normalized attachment path.
|
|
|
|
|
+ */
|
|
|
|
|
+ getAttachmentPath(setting) {
|
|
|
|
|
+ let root = "";
|
|
|
|
|
+ let attachPath = "";
|
|
|
|
|
+ if (this.attachmentFile !== void 0) {
|
|
|
|
|
+ const { extSetting } = getExtensionOverrideSetting(this.attachmentFile.extension, setting);
|
|
|
|
|
+ if (extSetting !== void 0) {
|
|
|
|
|
+ root = getRootPath(this.parentPath, extSetting);
|
|
|
|
|
+ attachPath = path.join(
|
|
|
|
|
+ root,
|
|
|
|
|
+ extSetting.attachmentPath.replace(`${SETTINGS_VARIABLES_NOTEPATH}`, this.parentPath).replace(`${SETTINGS_VARIABLES_NOTENAME}`, this.basename).replace(`${SETTINGS_VARIABLES_NOTEPARENT}`, this.parentName)
|
|
|
|
|
+ );
|
|
|
|
|
+ return (0, import_obsidian8.normalizePath)(attachPath);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ root = getRootPath(this.parentPath, setting);
|
|
|
|
|
+ debugLog("getAttachmentPath - root", root);
|
|
|
|
|
+ attachPath = path.join(
|
|
|
|
|
+ root,
|
|
|
|
|
+ setting.attachmentPath.replace(`${SETTINGS_VARIABLES_NOTEPATH}`, this.parentPath).replace(`${SETTINGS_VARIABLES_NOTENAME}`, this.basename).replace(`${SETTINGS_VARIABLES_NOTEPARENT}`, this.parentName)
|
|
|
|
|
+ );
|
|
|
|
|
+ return (0, import_obsidian8.normalizePath)(attachPath);
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+function getMetadata(file, attach) {
|
|
|
|
|
+ const parentPath = path.dirname(file);
|
|
|
|
|
+ const parentName = path.basename(parentPath);
|
|
|
|
|
+ const name = path.basename(file);
|
|
|
|
|
+ const extension = path.extname(file);
|
|
|
|
|
+ const basename = path.basename(file, extension);
|
|
|
|
|
+ return new Metadata(file, name, basename, extension, parentPath, parentName, attach);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// src/exclude.ts
|
|
|
|
|
+function isExcluded(path2, settings) {
|
|
|
|
|
+ debugLog("excludePathsArray: ", settings.excludePathsArray);
|
|
|
|
|
+ for (const excludedPath of settings.excludePathsArray) {
|
|
|
|
|
+ if (excludedPath.length === 0) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (settings.excludeSubpaths && path2.startsWith(excludedPath)) {
|
|
|
|
|
+ debugLog("isExcluded: ", path2);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (path2 === excludedPath) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return false;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// src/arrange.ts
|
|
|
|
|
+var ArrangeHandler = class {
|
|
|
|
|
+ constructor(settings, app2) {
|
|
|
|
|
+ this.pluginSettings = settings;
|
|
|
|
|
+ this.app = app2;
|
|
|
|
|
+ }
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Rearranges attachments that are linked by markdown or canvas.
|
|
|
|
|
+ * Only rearranges attachments if autoRenameAttachment is enabled in settings.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param {RearrangeType} type - The type of attachments to rearrange.
|
|
|
|
|
+ * @param {TFile} file - The file to which the attachments are linked (optional), if the type was "file", thi should be provided.
|
|
|
|
|
+ * @param {string} oldPath - The old path of the file (optional), used for rename event.
|
|
|
|
|
+ */
|
|
|
|
|
+ async rearrangeAttachment(type, file, oldPath) {
|
|
|
|
|
+ if (!this.pluginSettings.autoRenameAttachment) {
|
|
|
|
|
+ debugLog("rearrangeAttachment - autoRenameAttachment not enable");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ const attachments = await this.getAttachmentsInVault(this.pluginSettings, type, file, oldPath);
|
|
|
|
|
+ debugLog("rearrangeAttachment - attachments:", Object.keys(attachments).length, Object.entries(attachments));
|
|
|
|
|
+ for (const obNote of Object.keys(attachments)) {
|
|
|
|
|
+ const innerFile = this.app.vault.getAbstractFileByPath(obNote);
|
|
|
|
|
+ if (!(innerFile instanceof import_obsidian9.TFile) || isAttachment(this.app, this.pluginSettings, innerFile)) {
|
|
|
|
|
+ debugLog(`rearrangeAttachment - ${obNote} not exists or is attachment, skipped`);
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ const { setting } = getOverrideSetting(this.pluginSettings, innerFile);
|
|
|
|
|
+ if (attachments[obNote].size == 0) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ const md = getMetadata(obNote);
|
|
|
|
|
+ const attachPath = md.getAttachmentPath(setting);
|
|
|
|
|
+ if (!await this.app.vault.adapter.exists(attachPath, true)) {
|
|
|
|
|
+ if (oldPath != void 0 && await this.app.vault.adapter.exists(attachPath, false)) {
|
|
|
|
|
+ const mdOld = getMetadata(oldPath);
|
|
|
|
|
+ const attachPathOld = mdOld.getAttachmentPath(setting);
|
|
|
|
|
+ this.app.vault.adapter.rename(attachPathOld, attachPath);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ await this.app.vault.adapter.mkdir(attachPath);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ for (let link of attachments[obNote]) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ link = decodeURI(link);
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ console.log(`Invalid link: ${link}, err: ${err}`);
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ debugLog(`rearrangeAttachment - article: ${obNote} links: ${link}`);
|
|
|
|
|
+ const linkFile = this.app.vault.getAbstractFileByPath(link);
|
|
|
|
|
+ if (linkFile === null || !(linkFile instanceof import_obsidian9.TFile)) {
|
|
|
|
|
+ debugLog(`${link} not exists, skipped`);
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ const metadata = getMetadata(obNote, linkFile);
|
|
|
|
|
+ const attachName = await metadata.getAttachFileName(
|
|
|
|
|
+ setting,
|
|
|
|
|
+ this.pluginSettings.dateFormat,
|
|
|
|
|
+ linkFile,
|
|
|
|
|
+ this.app.vault.adapter,
|
|
|
|
|
+ this.pluginSettings
|
|
|
|
|
+ );
|
|
|
|
|
+ if (attachPath == path.dirname(link) && attachName === path.basename(link, path.extname(link))) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ const attachPathFolder = this.app.vault.getAbstractFileByPath(attachPath);
|
|
|
|
|
+ if (attachPathFolder === null || !(attachPathFolder instanceof import_obsidian9.TFolder)) {
|
|
|
|
|
+ debugLog(`${attachPath} not exists, skipped`);
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ const { name } = await deduplicateNewName(attachName + "." + path.extname(link), attachPathFolder);
|
|
|
|
|
+ debugLog("rearrangeAttachment - deduplicated name:", name);
|
|
|
|
|
+ await this.app.fileManager.renameFile(linkFile, path.join(attachPath, name));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Retrieves the attachments in the vault based on the specified settings and type.
|
|
|
|
|
+ * If a file is provided, only attachments related to that file will be returned.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param {AttachmentManagementPluginSettings} settings - The settings for the attachment management plugin.
|
|
|
|
|
+ * @param {RearrangeType} type - The type of attachments to retrieve.
|
|
|
|
|
+ * @param {TFile} [file] - The file to filter attachments by. Optional.
|
|
|
|
|
+ * @return {Promise<Record<string, Set<string>>>} - A promise that resolves to a record of attachments, where each key is a file name and each value is a set of associated attachment names.
|
|
|
|
|
+ */
|
|
|
|
|
+ async getAttachmentsInVault(settings, type, file, oldPath) {
|
|
|
|
|
+ let attachmentsRecord = {};
|
|
|
|
|
+ attachmentsRecord = await this.getAttachmentsInVaultByLinks(settings, type, file, oldPath);
|
|
|
|
|
+ return attachmentsRecord;
|
|
|
|
|
+ }
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Modified from https://github.com/ozntel/oz-clear-unused-images-obsidian/blob/master/src/util.ts#LL48C21-L48C21
|
|
|
|
|
+ * Retrieves a record of attachments in the vault based on the given settings and type.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param {AttachmentManagementPluginSettings} settings - The settings for the attachment management plugin.
|
|
|
|
|
+ * @param {RearrangeType} type - The type of attachments to retrieve.
|
|
|
|
|
+ * @param {TFile} file - The file to retrieve attachments for (optional).
|
|
|
|
|
+ * @return {Promise<Record<string, Set<string>>>} - A promise that resolves to a record of attachments.
|
|
|
|
|
+ */
|
|
|
|
|
+ async getAttachmentsInVaultByLinks(settings, type, file, oldPath) {
|
|
|
|
|
+ const attachmentsRecord = {};
|
|
|
|
|
+ let resolvedLinks = {};
|
|
|
|
|
+ let allFiles = [];
|
|
|
|
|
+ if (type == 1 /* LINKS */) {
|
|
|
|
|
+ resolvedLinks = this.app.metadataCache.resolvedLinks;
|
|
|
|
|
+ allFiles = this.app.vault.getFiles();
|
|
|
|
|
+ } else if (type == 0 /* ACTIVE */) {
|
|
|
|
|
+ const file2 = getActiveFile(this.app);
|
|
|
|
|
+ if (file2) {
|
|
|
|
|
+ if (file2.parent && isExcluded(file2.parent.path, this.pluginSettings) || isAttachment(this.app, this.pluginSettings, file2)) {
|
|
|
|
|
+ allFiles = [];
|
|
|
|
|
+ } else {
|
|
|
|
|
+ debugLog("getAttachmentsInVaultByLinks - active:", file2.path);
|
|
|
|
|
+ allFiles = [file2];
|
|
|
|
|
+ if (this.app.metadataCache.resolvedLinks[file2.path]) {
|
|
|
|
|
+ resolvedLinks[file2.path] = this.app.metadataCache.resolvedLinks[file2.path];
|
|
|
|
|
+ }
|
|
|
|
|
+ debugLog("getAttachmentsInVaultByLinks - resolvedLinks:", resolvedLinks);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } else if (type == 2 /* FILE */ && file != void 0) {
|
|
|
|
|
+ if (file.parent && isExcluded(file.parent.path, this.pluginSettings) || isAttachment(this.app, this.pluginSettings, file)) {
|
|
|
|
|
+ allFiles = [];
|
|
|
|
|
+ } else {
|
|
|
|
|
+ debugLog("getAttachmentsInVaultByLinks - file:", file.path);
|
|
|
|
|
+ allFiles = [file];
|
|
|
|
|
+ const rlinks = this.app.metadataCache.resolvedLinks[file.path];
|
|
|
|
|
+ if (rlinks) {
|
|
|
|
|
+ debugLog("getAttachmentsInVaultByLinks - rlinks:", rlinks);
|
|
|
|
|
+ resolvedLinks[file.path] = rlinks;
|
|
|
|
|
+ } else if (oldPath) {
|
|
|
|
|
+ debugLog("getAttachmentsInVaultByLinks - oldPath:", oldPath);
|
|
|
|
|
+ resolvedLinks[file.path] = this.app.metadataCache.resolvedLinks[oldPath];
|
|
|
|
|
+ }
|
|
|
|
|
+ debugLog("getAttachmentsInVaultByLinks - resolvedLinks:", resolvedLinks);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ debugLog("getAttachmentsInVaultByLinks - allFiles:", allFiles.length, allFiles);
|
|
|
|
|
+ if (resolvedLinks) {
|
|
|
|
|
+ for (const [mdFile, links] of Object.entries(resolvedLinks)) {
|
|
|
|
|
+ const attachmentsSet = /* @__PURE__ */ new Set();
|
|
|
|
|
+ if (links) {
|
|
|
|
|
+ for (const [filePath] of Object.entries(links)) {
|
|
|
|
|
+ if (isAttachment(this.app, settings, filePath)) {
|
|
|
|
|
+ this.addToSet(attachmentsSet, filePath);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ this.addToRecord(attachmentsRecord, mdFile, attachmentsSet);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return attachmentsRecord;
|
|
|
|
|
+ }
|
|
|
|
|
+ addToRecord(record, key, value) {
|
|
|
|
|
+ if (record[key] === void 0) {
|
|
|
|
|
+ record[key] = value;
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ const valueSet = record[key];
|
|
|
|
|
+ for (const val of value) {
|
|
|
|
|
+ this.addToSet(valueSet, val);
|
|
|
|
|
+ }
|
|
|
|
|
+ record[key] = valueSet;
|
|
|
|
|
+ }
|
|
|
|
|
+ addToSet(setObj, value) {
|
|
|
|
|
+ if (!setObj.has(value)) {
|
|
|
|
|
+ setObj.add(value);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ needToRename(settings, attachPath, attachName, noteName, link) {
|
|
|
|
|
+ const linkPath = path.dirname(link);
|
|
|
|
|
+ const linkName = path.basename(link, path.extname(link));
|
|
|
|
|
+ if (linkName.length !== attachName.length) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (attachPath !== linkPath) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (settings.attachFormat.includes(SETTINGS_VARIABLES_NOTENAME) && !linkName.includes(noteName)) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ const noNoteNameAttachFormat = settings.attachFormat.split(SETTINGS_VARIABLES_NOTENAME);
|
|
|
|
|
+ if (settings.attachFormat.includes(SETTINGS_VARIABLES_DATES)) {
|
|
|
|
|
+ for (const formatPart in noNoteNameAttachFormat) {
|
|
|
|
|
+ const splited = formatPart.split(SETTINGS_VARIABLES_DATES);
|
|
|
|
|
+ for (const part in splited) {
|
|
|
|
|
+ if (!linkName.includes(part)) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// src/model/confirm.ts
|
|
|
|
|
+var ConfirmModal = class extends import_obsidian10.Modal {
|
|
|
|
|
+ constructor(plugin) {
|
|
|
|
|
+ super(plugin.app);
|
|
|
|
|
+ this.plugin = plugin;
|
|
|
|
|
+ }
|
|
|
|
|
+ onOpen() {
|
|
|
|
|
+ const { contentEl } = this;
|
|
|
|
|
+ contentEl.empty();
|
|
|
|
|
+ const header = contentEl.createDiv({ cls: "amg-confirm-header" });
|
|
|
|
|
+ header.style.display = "flex";
|
|
|
|
|
+ header.style.alignItems = "center";
|
|
|
|
|
+ header.style.gap = "8px";
|
|
|
|
|
+ header.style.marginBottom = "12px";
|
|
|
|
|
+ const iconEl = header.createSpan({ cls: "amg-confirm-icon" });
|
|
|
|
|
+ iconEl.style.color = "var(--color-orange)";
|
|
|
|
|
+ iconEl.style.display = "inline-flex";
|
|
|
|
|
+ (0, import_obsidian10.setIcon)(iconEl, "alert-triangle");
|
|
|
|
|
+ header.createEl("h3", {
|
|
|
|
|
+ text: t("confirm.title"),
|
|
|
|
|
+ cls: "amg-confirm-title"
|
|
|
|
|
+ }).style.margin = "0";
|
|
|
|
|
+ const message = contentEl.createEl("p", {
|
|
|
|
|
+ text: t("confirm.message"),
|
|
|
|
|
+ cls: "amg-confirm-message"
|
|
|
|
|
+ });
|
|
|
|
|
+ message.style.margin = "0 0 16px 0";
|
|
|
|
|
+ message.style.lineHeight = "1.5";
|
|
|
|
|
+ new import_obsidian10.Setting(contentEl).addButton((btn) => {
|
|
|
|
|
+ btn.setButtonText(t("common.cancel")).onClick(() => {
|
|
|
|
|
+ this.close();
|
|
|
|
|
+ });
|
|
|
|
|
+ }).addButton(
|
|
|
|
|
+ (btn) => btn.setButtonText(t("confirm.continue")).setWarning().onClick(() => {
|
|
|
|
|
+ new ArrangeHandler(this.plugin.settings, this.plugin.app).rearrangeAttachment(1 /* LINKS */).then(() => new import_obsidian10.Notice(t("notices.arrangeCompleted"))).catch((err) => {
|
|
|
|
|
+ var _a;
|
|
|
|
|
+ return new import_obsidian10.Notice(`${t("notices.error.unknownError")}: ${(_a = err == null ? void 0 : err.message) != null ? _a : err}`);
|
|
|
|
|
+ }).finally(() => this.close());
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+ onClose() {
|
|
|
|
|
+ const { contentEl } = this;
|
|
|
|
|
+ contentEl.empty();
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// src/create.ts
|
|
|
|
|
+var import_obsidian11 = require("obsidian");
|
|
|
|
|
+var pendingRenameNotices = [];
|
|
|
|
|
+var flushRenameNotices = (0, import_obsidian11.debounce)(
|
|
|
|
|
+ () => {
|
|
|
|
|
+ if (pendingRenameNotices.length === 0) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (pendingRenameNotices.length === 1) {
|
|
|
|
|
+ const { from, to } = pendingRenameNotices[0];
|
|
|
|
|
+ new import_obsidian11.Notice(t("notices.fileRenamed", { from, to }));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ new import_obsidian11.Notice(t("notices.filesRenamedBatch", { count: pendingRenameNotices.length }));
|
|
|
|
|
+ }
|
|
|
|
|
+ pendingRenameNotices.length = 0;
|
|
|
|
|
+ },
|
|
|
|
|
+ 500,
|
|
|
|
|
+ true
|
|
|
|
|
+);
|
|
|
|
|
+function queueRenameNotice(from, to) {
|
|
|
|
|
+ pendingRenameNotices.push({ from, to });
|
|
|
|
|
+ flushRenameNotices();
|
|
|
|
|
+}
|
|
|
|
|
+var CreateHandler = class {
|
|
|
|
|
+ constructor(plugin, settings) {
|
|
|
|
|
+ this.plugin = plugin;
|
|
|
|
|
+ this.app = this.plugin.app;
|
|
|
|
|
+ this.settings = settings;
|
|
|
|
|
+ }
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Post-processing of created attachment file (for paste and drop event).
|
|
|
|
|
+ * @param attach - the attachment file to process
|
|
|
|
|
+ * @param source - the notes file that linked to attach
|
|
|
|
|
+ * @returns - none
|
|
|
|
|
+ */
|
|
|
|
|
+ processAttach(attach, source) {
|
|
|
|
|
+ if (source.parent && isExcluded(source.parent.path, this.settings)) {
|
|
|
|
|
+ debugLog("processAttach - not a file or exclude path:", source.path);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ const { setting } = getOverrideSetting(this.settings, source);
|
|
|
|
|
+ const { extSetting } = getExtensionOverrideSetting(attach.extension, setting);
|
|
|
|
|
+ debugLog("processAttach - file.extension:", attach.extension);
|
|
|
|
|
+ if (extSetting === void 0 && !isImage(attach.extension) && !isPastedImage(attach)) {
|
|
|
|
|
+ debugLog("renameFiles - no handle extension:", attach.extension);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ const metadata = getMetadata(source.path, attach);
|
|
|
|
|
+ debugLog("processAttach - metadata:", metadata);
|
|
|
|
|
+ const attachPath = metadata.getAttachmentPath(setting);
|
|
|
|
|
+ metadata.getAttachFileName(setting, this.settings.dateFormat, attach, this.app.vault.adapter).then((attachName) => {
|
|
|
|
|
+ attachName = attachName + "." + attach.extension;
|
|
|
|
|
+ this.app.vault.adapter.exists(attachPath, true).then(async (exists) => {
|
|
|
|
|
+ if (!exists) {
|
|
|
|
|
+ await this.app.vault.adapter.mkdir(attachPath);
|
|
|
|
|
+ debugLog("processAttach - create path:", attachPath);
|
|
|
|
|
+ }
|
|
|
|
|
+ }).finally(() => {
|
|
|
|
|
+ const attachPathFolder = this.app.vault.getAbstractFileByPath(attachPath);
|
|
|
|
|
+ deduplicateNewName(attachName, attachPathFolder).then(({ name }) => {
|
|
|
|
|
+ debugLog("processAttach - new path of file:", path.join(attachPath, name));
|
|
|
|
|
+ this.renameCreateFile(attach, attachPath, name, source);
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Rename the file specified by `@param file`, and update the link of the file if specified updateLink
|
|
|
|
|
+ * @param attach - file to rename
|
|
|
|
|
+ * @param attachPath - where to the renamed file will be move to
|
|
|
|
|
+ * @param attachName - name of the renamed file
|
|
|
|
|
+ * @param source - associated active file
|
|
|
|
|
+ * @returns - none
|
|
|
|
|
+ */
|
|
|
|
|
+ renameCreateFile(attach, attachPath, attachName, source) {
|
|
|
|
|
+ const dst = (0, import_obsidian11.normalizePath)(path.join(attachPath, attachName));
|
|
|
|
|
+ debugLog("renameFile - ", attach.path, " to ", dst);
|
|
|
|
|
+ const name = attach.name;
|
|
|
|
|
+ const originalBasename = attach.basename;
|
|
|
|
|
+ const oldLink = this.app.fileManager.generateMarkdownLink(attach, source.path);
|
|
|
|
|
+ this.app.vault.rename(attach, dst).then(() => {
|
|
|
|
|
+ if (name !== attachName) {
|
|
|
|
|
+ queueRenameNotice(name, attachName);
|
|
|
|
|
+ }
|
|
|
|
|
+ const newLink = this.app.fileManager.generateMarkdownLink(attach, source.path);
|
|
|
|
|
+ debugLog("renameFile - old link:", oldLink, "new link:", newLink);
|
|
|
|
|
+ this.updateLinkInSource(source, oldLink, newLink);
|
|
|
|
|
+ }).finally(() => {
|
|
|
|
|
+ const { setting } = getOverrideSetting(this.settings, source);
|
|
|
|
|
+ md5sum(this.app.vault.adapter, attach).then((md5) => {
|
|
|
|
|
+ saveOriginalName(this.settings, setting, attach.extension, {
|
|
|
|
|
+ n: originalBasename,
|
|
|
|
|
+ md5
|
|
|
|
|
+ });
|
|
|
|
|
+ this.plugin.saveData(this.settings);
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Update the old link to new link in the source file.
|
|
|
|
|
+ * For markdown files with an active editor, use editor.replaceRange to avoid file reload and cursor jump.
|
|
|
|
|
+ * For other cases (canvas, non-active files), fall back to adapter.process.
|
|
|
|
|
+ * @param source - the source file containing the link
|
|
|
|
|
+ * @param oldLink - the old link text to replace
|
|
|
|
|
+ * @param newLink - the new link text
|
|
|
|
|
+ */
|
|
|
|
|
+ updateLinkInSource(source, oldLink, newLink) {
|
|
|
|
|
+ if (oldLink === newLink) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ const mdView = this.app.workspace.getActiveViewOfType(import_obsidian11.MarkdownView);
|
|
|
|
|
+ if (mdView && mdView.file && mdView.file.path === source.path && mdView.editor) {
|
|
|
|
|
+ const editor = mdView.editor;
|
|
|
|
|
+ const content = editor.getValue();
|
|
|
|
|
+ const linkIndex = content.indexOf(oldLink);
|
|
|
|
|
+ if (linkIndex !== -1) {
|
|
|
|
|
+ const before = content.substring(0, linkIndex);
|
|
|
|
|
+ const lines = before.split("\n");
|
|
|
|
|
+ const fromLine = lines.length - 1;
|
|
|
|
|
+ const fromCh = lines[fromLine].length;
|
|
|
|
|
+ const oldLinkLines = oldLink.split("\n");
|
|
|
|
|
+ const toLine = fromLine + oldLinkLines.length - 1;
|
|
|
|
|
+ const toCh = oldLinkLines.length > 1 ? oldLinkLines[oldLinkLines.length - 1].length : fromCh + oldLink.length;
|
|
|
|
|
+ editor.replaceRange(newLink, { line: fromLine, ch: fromCh }, { line: toLine, ch: toCh });
|
|
|
|
|
+ debugLog("updateLinkInSource - updated via editor API");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ debugLog("updateLinkInSource - falling back to adapter.process");
|
|
|
|
|
+ this.app.vault.adapter.process(source.path, (data) => {
|
|
|
|
|
+ return data.replace(oldLink, newLink);
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// src/main.ts
|
|
|
|
|
+var AttachmentManagementPlugin = class extends import_obsidian12.Plugin {
|
|
|
|
|
+ constructor() {
|
|
|
|
|
+ super(...arguments);
|
|
|
|
|
+ this.createdQueue = [];
|
|
|
|
|
+ }
|
|
|
|
|
+ async onload() {
|
|
|
|
|
+ await this.loadSettings();
|
|
|
|
|
+ initI18n();
|
|
|
|
|
+ console.log(`Plugin loading: ${this.manifest.name} v.${this.manifest.version}`);
|
|
|
|
|
+ this.app.workspace.onLayoutReady(() => {
|
|
|
|
|
+ this.initCommands();
|
|
|
|
|
+ this.registerEvent(
|
|
|
|
|
+ this.app.workspace.on("file-menu", async (menu, file) => {
|
|
|
|
|
+ if (file.parent && isExcluded(file.parent.path, this.settings) || isAttachment(this.app, this.settings, file)) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ menu.addItem((item) => {
|
|
|
|
|
+ item.setTitle(t("override.menuTitle")).setIcon("image-plus").onClick(async () => {
|
|
|
|
|
+ const { setting } = getOverrideSetting(this.settings, file);
|
|
|
|
|
+ const fileSetting = Object.assign({}, setting);
|
|
|
|
|
+ this.overrideConfiguration(file, fileSetting);
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ this.registerEvent(
|
|
|
|
|
+ this.app.vault.on("create", async (file) => {
|
|
|
|
|
+ debugLog("on create event - file:", file.path);
|
|
|
|
|
+ if (!(file instanceof import_obsidian12.TFile)) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ const curentTime = (/* @__PURE__ */ new Date()).getTime();
|
|
|
|
|
+ const timeGapMs = curentTime - file.stat.mtime;
|
|
|
|
|
+ const timeGapCs = curentTime - file.stat.ctime;
|
|
|
|
|
+ if (timeGapMs > 1e3 || timeGapCs > 1e3 || isMarkdownFile(file.extension) || isCanvasFile(file.extension)) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (matchExtension(file.extension, this.settings.excludeExtensionPattern)) {
|
|
|
|
|
+ debugLog("create - excluded file by extension", file);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ this.createdQueue.push(file);
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ this.registerEvent(
|
|
|
|
|
+ this.app.vault.on("modify", (file) => {
|
|
|
|
|
+ debugLog("on modify event - create queue:", this.createdQueue);
|
|
|
|
|
+ if (this.createdQueue.length < 1 || !(file instanceof import_obsidian12.TFile)) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ debugLog("on modify event - file:", file.path);
|
|
|
|
|
+ this.app.vault.cachedRead(file).then((data) => {
|
|
|
|
|
+ const f = this.createdQueue.first();
|
|
|
|
|
+ if (f != void 0) {
|
|
|
|
|
+ this.app.vault.adapter.exists(f.path, true).then((exist) => {
|
|
|
|
|
+ if (exist) {
|
|
|
|
|
+ const processor = new CreateHandler(this, this.settings);
|
|
|
|
|
+ const link = this.app.fileManager.generateMarkdownLink(f, file.path);
|
|
|
|
|
+ if (file.extension == "md" && data.indexOf(link) != -1 || file.extension == "canvas" && data.indexOf(f.path) != -1) {
|
|
|
|
|
+ processor.processAttach(f, file);
|
|
|
|
|
+ this.createdQueue.remove(f);
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ debugLog("on modify event - file does not exist:", f.path);
|
|
|
|
|
+ this.createdQueue.remove(f);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ this.registerEvent(
|
|
|
|
|
+ // when trigger a rename event on folder, for each file/folder in this renamed folder (include itself) will trigger this event
|
|
|
|
|
+ this.app.vault.on("rename", async (file, oldPath) => {
|
|
|
|
|
+ debugLog("on rename event - new path and old path:", file.path, oldPath);
|
|
|
|
|
+ if (isAttachment(this.app, this.settings, file)) {
|
|
|
|
|
+ debugLog("rename - not processing rename on attachment:", file.path);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ const { setting } = getRenameOverrideSetting(this.settings, file, oldPath);
|
|
|
|
|
+ debugLog("rename - using settings:", setting);
|
|
|
|
|
+ if (setting.type === "FOLDER" /* FOLDER */ || setting.type === "FILE" /* FILE */) {
|
|
|
|
|
+ updateOverrideSetting(this.settings, file, oldPath);
|
|
|
|
|
+ this.saveSettings();
|
|
|
|
|
+ }
|
|
|
|
|
+ debugLog("rename - updated settings:", setting);
|
|
|
|
|
+ if (!this.settings.autoRenameAttachment) {
|
|
|
|
|
+ debugLog("rename - auto rename not enabled:", this.settings.autoRenameAttachment);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (file instanceof import_obsidian12.TFile) {
|
|
|
|
|
+ if (file.parent && isExcluded(file.parent.path, this.settings)) {
|
|
|
|
|
+ debugLog("rename - exclude path:", file.parent.path);
|
|
|
|
|
+ new import_obsidian12.Notice(t("notices.fileExcluded", { path: file.path }));
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ await new ArrangeHandler(this.settings, this.app).rearrangeAttachment(2 /* FILE */, file, oldPath);
|
|
|
|
|
+ const oldMetadata = getMetadata(oldPath);
|
|
|
|
|
+ const oldAttachPath = oldMetadata.getAttachmentPath(setting);
|
|
|
|
|
+ this.app.vault.adapter.exists(oldAttachPath, true).then((exists) => {
|
|
|
|
|
+ if (exists) {
|
|
|
|
|
+ checkEmptyFolder(this.app.vault.adapter, oldAttachPath).then((empty) => {
|
|
|
|
|
+ if (empty) {
|
|
|
|
|
+ this.app.vault.adapter.rmdir(oldAttachPath, true);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ } else if (file instanceof import_obsidian12.TFolder) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ this.registerEvent(
|
|
|
|
|
+ this.app.vault.on("delete", async (file) => {
|
|
|
|
|
+ debugLog("on delete event - file path:", file.path);
|
|
|
|
|
+ if (file.parent && isExcluded(file.parent.path, this.settings) || isAttachment(this.app, this.settings, file)) {
|
|
|
|
|
+ debugLog("delete - exclude path or the file is an attachment:", file.path);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (file instanceof import_obsidian12.TFile) {
|
|
|
|
|
+ const oldMetadata = getMetadata(file.path);
|
|
|
|
|
+ const { setting } = getOverrideSetting(this.settings, file);
|
|
|
|
|
+ const oldAttachPath = oldMetadata.getAttachmentPath(setting);
|
|
|
|
|
+ this.app.vault.adapter.exists(oldAttachPath, true).then((exists) => {
|
|
|
|
|
+ if (exists) {
|
|
|
|
|
+ checkEmptyFolder(this.app.vault.adapter, oldAttachPath).then((empty) => {
|
|
|
|
|
+ if (empty) {
|
|
|
|
|
+ this.app.vault.adapter.rmdir(oldAttachPath, true);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ if (deleteOverrideSetting(this.settings, file)) {
|
|
|
|
|
+ await this.saveSettings();
|
|
|
|
|
+ new import_obsidian12.Notice(t("notices.overrideRemoved", { path: file.path }));
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ this.addSettingTab(new AttachmentManagementSettingTab(this.app, this));
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ async overrideConfiguration(file, setting) {
|
|
|
|
|
+ new OverrideModal(this, file, setting).open();
|
|
|
|
|
+ }
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Initializes and registers the plugin's commands
|
|
|
|
|
+ * This method is responsible for setting up the user interface by adding various commands.
|
|
|
|
|
+ * These commands include settings overrides, resetting settings, clearing unused original name storage,
|
|
|
|
|
+ * and rearranging attachments.
|
|
|
|
|
+ *
|
|
|
|
|
+ * Note: The actual implementation of each command is not included in this method and needs to be
|
|
|
|
|
+ * defined separately asynchronously.
|
|
|
|
|
+ *
|
|
|
|
|
+ * Warning: Make sure you have checked for errors while implementing the functionality of each command.
|
|
|
|
|
+ */
|
|
|
|
|
+ initCommands() {
|
|
|
|
|
+ this.addCommand({
|
|
|
|
|
+ id: "attachment-management-rearrange-all-links",
|
|
|
|
|
+ name: t("commands.rearrangeAllLinks"),
|
|
|
|
|
+ callback: async () => {
|
|
|
|
|
+ new ConfirmModal(this).open();
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ this.addCommand({
|
|
|
|
|
+ id: "attachment-management-rearrange-active-links",
|
|
|
|
|
+ name: t("commands.rearrangeActiveLinks"),
|
|
|
|
|
+ callback: async () => {
|
|
|
|
|
+ new ArrangeHandler(this.settings, this.app).rearrangeAttachment(0 /* ACTIVE */).finally(() => {
|
|
|
|
|
+ new import_obsidian12.Notice(t("notices.arrangeCompleted"));
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ this.addCommand({
|
|
|
|
|
+ id: "attachment-management-override-setting",
|
|
|
|
|
+ name: "Overriding setting",
|
|
|
|
|
+ checkCallback: (checking) => {
|
|
|
|
|
+ const file = getActiveFile(this.app);
|
|
|
|
|
+ if (file) {
|
|
|
|
|
+ if (isAttachment(this.app, this.settings, file)) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!checking) {
|
|
|
|
|
+ if (file.parent && isExcluded(file.parent.path, this.settings)) {
|
|
|
|
|
+ new import_obsidian12.Notice(t("notices.fileExcluded", { path: file.path }));
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ const { setting } = getOverrideSetting(this.settings, file);
|
|
|
|
|
+ const fileSetting = Object.assign({}, setting);
|
|
|
|
|
+ this.overrideConfiguration(file, fileSetting);
|
|
|
|
|
+ }
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ this.addCommand({
|
|
|
|
|
+ id: "attachment-management-reset-override-setting",
|
|
|
|
|
+ name: t("commands.resetOverrideSetting"),
|
|
|
|
|
+ checkCallback: (checking) => {
|
|
|
|
|
+ const file = getActiveFile(this.app);
|
|
|
|
|
+ if (file) {
|
|
|
|
|
+ if (isAttachment(this.app, this.settings, file)) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!checking) {
|
|
|
|
|
+ if (file.parent && isExcluded(file.parent.path, this.settings)) {
|
|
|
|
|
+ new import_obsidian12.Notice(t("notices.fileExcluded", { path: file.path }));
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ delete this.settings.overridePath[file.path];
|
|
|
|
|
+ this.saveSettings().finally(() => {
|
|
|
|
|
+ new import_obsidian12.Notice(t("notices.resetAttachmentSetting", { path: file.path }));
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ this.addCommand({
|
|
|
|
|
+ id: "attachment-management-clear-unused-originalname-storage",
|
|
|
|
|
+ name: t("commands.clearUnusedStorage"),
|
|
|
|
|
+ callback: async () => {
|
|
|
|
|
+ const attachments = await new ArrangeHandler(this.settings, this.app).getAttachmentsInVault(
|
|
|
|
|
+ this.settings,
|
|
|
|
|
+ 1 /* LINKS */
|
|
|
|
|
+ );
|
|
|
|
|
+ const validMd5s = /* @__PURE__ */ new Set();
|
|
|
|
|
+ for (const attachs of Object.values(attachments)) {
|
|
|
|
|
+ for (const attach of attachs) {
|
|
|
|
|
+ const link = decodeURI(attach);
|
|
|
|
|
+ const linkFile = this.app.vault.getAbstractFileByPath(link);
|
|
|
|
|
+ if (linkFile instanceof import_obsidian12.TFile) {
|
|
|
|
|
+ validMd5s.add(await md5sum(this.app.vault.adapter, linkFile));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ this.settings.originalNameStorage = this.settings.originalNameStorage.filter((s) => validMd5s.has(s.md5));
|
|
|
|
|
+ debugLog("clearUnusedOriginalNameStorage - storage:", this.settings.originalNameStorage);
|
|
|
|
|
+ await this.saveSettings();
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ async loadSettings() {
|
|
|
|
|
+ this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
|
|
|
|
|
+ }
|
|
|
|
|
+ async saveSettings() {
|
|
|
|
|
+ await this.saveData(this.settings);
|
|
|
|
|
+ }
|
|
|
|
|
+ async onunload() {
|
|
|
|
|
+ console.log("unloading attachment management.");
|
|
|
|
|
+ this.createdQueue = [];
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/* nosourcemap */
|