/* 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); // main.ts var main_exports = {}; __export(main_exports, { default: () => MetadataMenu }); module.exports = __toCommonJS(main_exports); // env.js window.MDM_DEBUG = false; // main.ts var import_obsidian85 = require("obsidian"); // src/commands/paletteCommands.ts var import_obsidian66 = require("obsidian"); // src/components/FieldsModal.ts var import_obsidian65 = require("obsidian"); // src/note/note.ts var import_obsidian64 = require("obsidian"); // src/types/lookupTypes.ts var BuiltinSummarizing = /* @__PURE__ */ ((BuiltinSummarizing2) => { BuiltinSummarizing2["Sum"] = "Sum"; BuiltinSummarizing2["Count"] = "Count"; BuiltinSummarizing2["CountAll"] = "CountAll"; BuiltinSummarizing2["Average"] = "Average"; BuiltinSummarizing2["Max"] = "Max"; BuiltinSummarizing2["Min"] = "Min"; return BuiltinSummarizing2; })(BuiltinSummarizing || {}); var BuiltinSummarizingFunctionDescription = { "Sum": "Returns the sum of <{{summarizedFieldName}}> fields in the pages matching the query", "Count": "Counts all pages matching the query where <{{summarizedFieldName}}> is non empty", "CountAll": "Counts all pages matching the query (including empty fields)", "Average": "Returns the average value of <{{summarizedFieldName}}> fields in the pages matching the query", "Max": "Returns the maximum value of <{{summarizedFieldName}}> fields in the pages matching the query", "Min": "Returns the minimum value of <{{summarizedFieldName}}> fields in the pages matching the query" }; var BuiltinSummarizingFunction = { "Sum": 'const i=0;const sum = pages.reduce((p, c) => p + c["{{summarizedFieldName}}"], i); return sum', "CountAll": "return pages.length", "Count": 'return pages.filter(p => !!p["{{summarizedFieldName}}"]).length', "Average": 'const i=0.0;const sum = pages.reduce((p, c) => p + c["{{summarizedFieldName}}"], i); return sum / pages.length', "Max": 'return pages.reduce((p,c) => p["{{summarizedFieldName}}"] >= c["{{summarizedFieldName}}"] ? p : c)["{{summarizedFieldName}}"]', "Min": 'return pages.reduce((p,c) => p["{{summarizedFieldName}}"]!==null && p["{{summarizedFieldName}}"] <= c["{{summarizedFieldName}}"] ? p : c)["{{summarizedFieldName}}"]' }; var Type = /* @__PURE__ */ ((Type3) => { Type3["LinksList"] = "LinksList"; Type3["LinksBulletList"] = "LinksBulletList"; Type3["BuiltinSummarizing"] = "BuiltinSummarizing"; Type3["CustomList"] = "CustomList"; Type3["CustomBulletList"] = "CustomBulletList"; Type3["CustomSummarizing"] = "CustomSummarizing"; return Type3; })(Type || {}); var ShortDescription = { "LinksList": "Inline list of links", "LinksBulletList": "Bullet list of links", "BuiltinSummarizing": "", "CustomList": "Inline list of customized links", "CustomBulletList": "Bullet list of customized links", "CustomSummarizing": "Custom summarizing function" }; var Description = { "LinksList": "List of related links displayed inline", "LinksBulletList": "List of related links displayed below the field", "BuiltinSummarizing": "Built-in summarizing function", "CustomList": "Custom list rendering function displayed inline", "CustomBulletList": "Custom list rendering function displayed below the field", "CustomSummarizing": "Custom summarizing function" }; var OptionLabel = { "LinksList": "", "LinksBulletList": "", "BuiltinSummarizing": "Built-in summarize function:", "CustomList": "Query's results' list's rendering function:", "CustomBulletList": "Query's results' list's rendering function:", "CustomSummarizing": "Query's results' list's summarizing function:" }; var OptionSubLabel = { "LinksList": "", "LinksBulletList": "", "BuiltinSummarizing": "", "CustomList": `function(page) { return ; }`, "CustomBulletList": `function(page) { return ; }`, "CustomSummarizing": `function(page) { return ; }` }; var Helper = { "LinksList": "", "LinksBulletList": "", "BuiltinSummarizing": "", "CustomList": 'Javascript string, the "page" (dataview page type) variable is available\nexample 1: page.file.name\nexample 2: `${page.file.name} of gender ${page.gender}`', "CustomBulletList": 'Javascript string, the "page" (dataview page type) variable is available\nexample 1: page.file.name\nexample 2: `${page.file.name} of gender ${page.gender}`', "CustomSummarizing": 'Javascript string, the "pages" (dataview pages type) variable is available\nexample: \nconst initialValue = 0;\nconst sumWithInitial = pages.reduce(\n (previousValue, currentValue) => previousValue + currentValue,\n initialValue\n);\nreturn `${sumWithInitial}`\n' }; var Default = { "LinksList": "", "LinksBulletList": "", "BuiltinSummarizing": "Count" /* Count */, "CustomList": "page.file.name", "CustomBulletList": "page.file.name", "CustomSummarizing": "return pages.length" }; var bulletListLookupTypes = [ "LinksBulletList" /* LinksBulletList */, "CustomBulletList" /* CustomBulletList */ ]; var statusIcon = { "mayHaveChanged": "refresh-ccw", "error": "file-warning", "upToDate": "file-check", "changed": "refresh-ccw" }; // src/utils/parser.ts var fieldComponents = ["inQuote", "inList", "preSpacer", "startStyle", "attribute", "endStyle", "beforeSeparatorSpacer", "afterSeparatorSpacer", "values"]; var genericFieldRegex = "(?>*(\\s+)?)?(?- )?(?(\\s+)?)?(?[_\\*~`]*)(?[-\\w\\p{Letter}\\p{Emoji_Presentation}\\s]*)(?[_\\*~`]*)(?\\s*)"; var fullLineRegex = new RegExp(`^\\s*${genericFieldRegex}::(?\\s*)(?.*)?`, "u"); var inSentenceRegexBrackets = new RegExp(`\\[${genericFieldRegex}::(?\\s*)(?[^\\]]+)?\\]`, "gu"); var inSentenceRegexPar = new RegExp(`\\(${genericFieldRegex}::(?\\s*)(?[^\\)]+)?\\)`, "gu"); var LinkRegex = new RegExp(`\\[\\[(?[^\\|]*)(\\|)?(?.*)?\\]\\]`); var getLink = (linkText, source) => { var _a, _b, _c, _d, _e; const fR = (_a = `${linkText}`) == null ? void 0 : _a.match(LinkRegex); if ((_b = fR == null ? void 0 : fR.groups) == null ? void 0 : _b.target) { const path = (_e = app.metadataCache.getFirstLinkpathDest((_c = fR == null ? void 0 : fR.groups) == null ? void 0 : _c.target, (source == null ? void 0 : source.path) || ((_d = fR == null ? void 0 : fR.groups) == null ? void 0 : _d.target))) == null ? void 0 : _e.path; if (path) { return { path, alias: fR.groups.alias }; } } return; }; var extractLinks = (rawContent) => { var _a, _b; const links = []; const linksIterator = rawContent.matchAll(/\[\[(?:[^\]]*)\]\]/g); let rawLink; while (rawLink = (_b = (_a = linksIterator.next()) == null ? void 0 : _a.value) == null ? void 0 : _b[0]) { links.push(rawLink); } return links; }; var encodeLink = (value) => { return value ? value.replace(/\[\[/g, "\u20AC\xF9").replace(/\]\]/g, "\xF9\u20AC") : value; }; var decodeLink = (value) => { return value ? value.replace(/€ù/gu, "[[").replace(/ù€/gu, "]]") : value; }; var frontMatterLineField = (line) => { const frontMatterRegex = new RegExp(/(?\s*)(?-\s)?(?[-\w\p{Letter}\p{Emoji_Presentation}\s\(\)]*[^\s])(?\s*):(?\s*)(?.*)/u); const fR = line.match(frontMatterRegex); if (fR == null ? void 0 : fR.groups) { return { attribute: fR == null ? void 0 : fR.groups.attribute, indentation: fR == null ? void 0 : fR.groups.indentation, list: fR == null ? void 0 : fR.groups.list, beforeSeparatorSpacer: fR == null ? void 0 : fR.groups.beforeSeparatorSpacer, afterSeparatorSpacer: fR == null ? void 0 : fR.groups.afterSeparatorSpacer, values: fR == null ? void 0 : fR.groups.values }; } return { attribute: void 0, indentation: void 0, list: void 0, beforeSeparatorSpacer: void 0, afterSeparatorSpacer: void 0, values: void 0 }; }; var getLineFields = (line) => { const fields = []; const fR = line.match(fullLineRegex); if (fR == null ? void 0 : fR.groups) { const { attribute, inList, inQuote, preSpacer, startStyle, endStyle, beforeSeparatorSpacer, afterSeparatorSpacer, values } = fR.groups; fields.push({ attribute, values: values || "", index: 0, length: line.length, inList, inQuote, preSpacer, startStyle, endStyle, beforeSeparatorSpacer, afterSeparatorSpacer }); } else { const sRBk = encodeLink(line).matchAll(inSentenceRegexBrackets); let next = sRBk.next(); while (!next.done) { if (next.value.groups) { const { attribute, values, inList, inQuote, preSpacer, startStyle, endStyle, beforeSeparatorSpacer, afterSeparatorSpacer } = next.value.groups; fields.push({ attribute, values: decodeLink(values), index: next.value.index || 0, length: next.value[0].length, inList, inQuote, preSpacer, startStyle, endStyle, beforeSeparatorSpacer, afterSeparatorSpacer, enclosureType: "brackets" }); } next = sRBk.next(); } const sRBc = encodeLink(line).matchAll(inSentenceRegexPar); next = sRBc.next(); while (!next.done) { if (next.value.groups) { const { attribute, values, inList, inQuote, preSpacer, startStyle, endStyle, beforeSeparatorSpacer, afterSeparatorSpacer } = next.value.groups; fields.push({ attribute, values: decodeLink(values), index: next.value.index || 0, length: next.value[0].length, inList, inQuote, preSpacer, startStyle, endStyle, beforeSeparatorSpacer, afterSeparatorSpacer, enclosureType: "parenthesis" }); } next = sRBc.next(); } } fields.sort((a, b) => { if (a.index < b.index) return -1; if (a.index > b.index) return 1; return 0; }); return fields; }; // src/types/dataviewTypes.ts var fieldDecorations = [ "Code", "Italic", "Bold", "Strikethrough" ]; var FieldHTMLTagMap = { "Code": "pre", "Italic": "i", "Bold": "b", "Strikethrough": "s" }; var FieldStyleLabel = { "code": "Code", "italic": "Italic", "bold": "Bold", "strikethrough": "Strikethrough" }; var FieldStyleKey = { "Code": "code", "Italic": "italic", "Bold": "bold", "Strikethrough": "strikethrough" }; var FieldStyleSyntax = { "Code": "`", "Italic": "*", "Bold": "**", "Strikethrough": "~~" }; var buildStartStyle = (style) => { let startStyle = ""; FieldStyleLabel.Italic; if (style[FieldStyleKey.Italic]) startStyle += FieldStyleSyntax.Italic; if (style[FieldStyleKey.Strikethrough]) startStyle += FieldStyleSyntax.Strikethrough; if (style[FieldStyleKey.Bold]) startStyle += FieldStyleSyntax.Bold; if (style[FieldStyleKey.Code]) startStyle += FieldStyleSyntax.Code; return startStyle; }; var buildEndStyle = (style) => { let endStyle = ""; if (style[FieldStyleKey.Code]) endStyle += FieldStyleSyntax.Code; if (style[FieldStyleKey.Bold]) endStyle += FieldStyleSyntax.Bold; if (style[FieldStyleKey.Strikethrough]) endStyle += FieldStyleSyntax.Strikethrough; if (style[FieldStyleKey.Italic]) endStyle += FieldStyleSyntax.Italic; return endStyle; }; // src/fields/Field.ts var import_obsidian63 = require("obsidian"); // node_modules/crypto-random-string/core.js var urlSafeCharacters = [..."abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~"]; var numericCharacters = [..."0123456789"]; var distinguishableCharacters = [..."CDEHKMPRTUWXY012458"]; var asciiPrintableCharacters = [..."!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"]; var alphanumericCharacters = [..."ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"]; var readUInt16LE = (uInt8Array, offset2) => uInt8Array[offset2] + (uInt8Array[offset2 + 1] << 8); var generateForCustomCharacters = (length, characters, randomBytes) => { const characterCount = characters.length; const maxValidSelector = Math.floor(65536 / characterCount) * characterCount - 1; const entropyLength = 2 * Math.ceil(1.1 * length); let string2 = ""; let stringLength = 0; while (stringLength < length) { const entropy = randomBytes(entropyLength); let entropyPosition = 0; while (entropyPosition < entropyLength && stringLength < length) { const entropyValue = readUInt16LE(entropy, entropyPosition); entropyPosition += 2; if (entropyValue > maxValidSelector) { continue; } string2 += characters[entropyValue % characterCount]; stringLength++; } } return string2; }; var generateForCustomCharactersAsync = async (length, characters, randomBytesAsync) => { const characterCount = characters.length; const maxValidSelector = Math.floor(65536 / characterCount) * characterCount - 1; const entropyLength = 2 * Math.ceil(1.1 * length); let string2 = ""; let stringLength = 0; while (stringLength < length) { const entropy = await randomBytesAsync(entropyLength); let entropyPosition = 0; while (entropyPosition < entropyLength && stringLength < length) { const entropyValue = readUInt16LE(entropy, entropyPosition); entropyPosition += 2; if (entropyValue > maxValidSelector) { continue; } string2 += characters[entropyValue % characterCount]; stringLength++; } } return string2; }; var allowedTypes = /* @__PURE__ */ new Set([ void 0, "hex", "base64", "url-safe", "numeric", "distinguishable", "ascii-printable", "alphanumeric" ]); var createGenerator = (generateForCustomCharacters2, specialRandomBytes2, randomBytes) => ({ length, type, characters }) => { if (!(length >= 0 && Number.isFinite(length))) { throw new TypeError("Expected a `length` to be a non-negative finite number"); } if (type !== void 0 && characters !== void 0) { throw new TypeError("Expected either `type` or `characters`"); } if (characters !== void 0 && typeof characters !== "string") { throw new TypeError("Expected `characters` to be string"); } if (!allowedTypes.has(type)) { throw new TypeError(`Unknown type: ${type}`); } if (type === void 0 && characters === void 0) { type = "hex"; } if (type === "hex" || type === void 0 && characters === void 0) { return specialRandomBytes2(Math.ceil(length * 0.5), "hex", length); } if (type === "base64") { return specialRandomBytes2(Math.ceil(length * 0.75), "base64", length); } if (type === "url-safe") { return generateForCustomCharacters2(length, urlSafeCharacters, randomBytes); } if (type === "numeric") { return generateForCustomCharacters2(length, numericCharacters, randomBytes); } if (type === "distinguishable") { return generateForCustomCharacters2(length, distinguishableCharacters, randomBytes); } if (type === "ascii-printable") { return generateForCustomCharacters2(length, asciiPrintableCharacters, randomBytes); } if (type === "alphanumeric") { return generateForCustomCharacters2(length, alphanumericCharacters, randomBytes); } if (characters.length === 0) { throw new TypeError("Expected `characters` string length to be greater than or equal to 1"); } if (characters.length > 65536) { throw new TypeError("Expected `characters` string length to be less or equal to 65536"); } return generateForCustomCharacters2(length, characters, randomBytes); }; function createStringGenerator(specialRandomBytes2, randomBytes) { return createGenerator(generateForCustomCharacters, specialRandomBytes2, randomBytes); } function createAsyncStringGenerator(specialRandomBytesAsync, randomBytesAsync) { return createGenerator(generateForCustomCharactersAsync, specialRandomBytesAsync, randomBytesAsync); } // node_modules/crypto-random-string/browser.js var toHex = (uInt8Array) => [...uInt8Array].map((byte) => byte.toString(16).padStart(2, "0")).join(""); var toBase64 = (uInt8Array) => btoa(String.fromCodePoint(...uInt8Array)); var maxEntropy = 65536; function getRandomValues(byteLength) { const generatedBytes = new Uint8Array(byteLength); for (let totalGeneratedBytes = 0; totalGeneratedBytes < byteLength; totalGeneratedBytes += maxEntropy) { generatedBytes.set( crypto.getRandomValues(new Uint8Array(Math.min(maxEntropy, byteLength - totalGeneratedBytes))), totalGeneratedBytes ); } return generatedBytes; } function specialRandomBytes(byteLength, type, length) { const generatedBytes = getRandomValues(byteLength); const convert = type === "hex" ? toHex : toBase64; return convert(generatedBytes).slice(0, length); } var browser_default = createStringGenerator(specialRandomBytes, getRandomValues); var cryptoRandomStringAsync = createAsyncStringGenerator(specialRandomBytes, getRandomValues); // src/fields/models/Input.ts var import_obsidian4 = require("obsidian"); // src/fields/base/BaseModal.ts var import_obsidian3 = require("obsidian"); // src/commands/getValues.ts var import_obsidian = require("obsidian"); async function getValues(plugin, fileOrfilePath, attribute) { let file; if (fileOrfilePath instanceof import_obsidian.TFile) { file = fileOrfilePath; } else { const _file = plugin.app.vault.getAbstractFileByPath(fileOrfilePath); if (_file instanceof import_obsidian.TFile && _file.extension == "md") { file = _file; } else { throw Error("path doesn't correspond to a proper file"); } } const eF = await Note.getExistingFields(plugin, file); return eF.filter((_ef) => _ef.field.name === attribute).map((_eF) => _eF.value); } async function getExistingFieldForIndexedPath(plugin, fileOrfilePath, indexedPath) { let file; if (fileOrfilePath instanceof import_obsidian.TFile) { file = fileOrfilePath; } else { const _file = plugin.app.vault.getAbstractFileByPath(fileOrfilePath); if (_file instanceof import_obsidian.TFile && _file.extension == "md") { file = _file; } else { throw Error("path doesn't correspond to a proper file"); } } const eF = await Note.getExistingFieldForIndexedPath(plugin, file, indexedPath); return eF; } async function getValuesForIndexedPath(plugin, fileOrfilePath, indexedPath) { const eF = await getExistingFieldForIndexedPath(plugin, fileOrfilePath, indexedPath); return eF == null ? void 0 : eF.value; } // src/utils/fileUtils.ts var import_obsidian2 = require("obsidian"); function resolve_tfolder(plugin, folder_str) { folder_str = (0, import_obsidian2.normalizePath)(folder_str); const folder = plugin.app.vault.getAbstractFileByPath(folder_str); if (!folder) { throw new Error(`Folder "${folder_str}" doesn't exist`); } if (!(folder instanceof import_obsidian2.TFolder)) { throw new Error(`${folder_str} is a file, not a folder`); } return folder; } function get_tfiles_from_folder(plugin, folder_str) { const folder = resolve_tfolder(plugin, folder_str); const files = []; import_obsidian2.Vault.recurseChildren(folder, (file) => { if (file instanceof import_obsidian2.TFile) { files.push(file); } }); files.sort((a, b) => { return a.basename.localeCompare(b.basename); }); return files; } function getFileFromFileOrPath(plugin, fileOrFilePath) { let file; if (fileOrFilePath instanceof import_obsidian2.TFile) { file = fileOrFilePath; } else { const _file = plugin.app.vault.getAbstractFileByPath(fileOrFilePath); if (_file instanceof import_obsidian2.TFile && _file.extension == "md") { file = _file; } else { throw Error("path doesn't correspond to a proper file"); } } return file; } function getFrontmatterPosition(plugin, file) { var _a; const cache = plugin.app.metadataCache.getFileCache(file); if (cache) { if (cache.frontmatterPosition) { return cache.frontmatterPosition; } else if (cache.frontmatter) { return cache.frontmatter.position; } else { const firstSection = (_a = cache.sections) == null ? void 0 : _a[0]; if ((firstSection == null ? void 0 : firstSection.type) === "yaml") { return firstSection.position; } else { return { start: void 0, end: void 0 }; } } } else { return { start: void 0, end: void 0 }; } } // src/commands/postValues.ts async function postValues(plugin, payload, fileOrFilePath, lineNumber, asList = false, asBlockquote = false) { var _a; if (payload.some((_p) => !_p.indexedPath)) { console.error("One payload's field is missing an indexed path"); return; } const file = getFileFromFileOrPath(plugin, fileOrFilePath); const note = await Note.buildNote(plugin, file); await note.createOrUpdateFields(payload, lineNumber, asList, asBlockquote); const changes = []; for (const item of payload) { const { id, index } = getIdAndIndex(item.indexedPath.split("____").last()); const field2 = (_a = plugin.fieldIndex.filesFields.get(file.path)) == null ? void 0 : _a.find((f) => f.id === id); const fieldName = field2 == null ? void 0 : field2.name; const value = item.payload.value; changes.push({ indexedPath: item.indexedPath, fieldName, index, value }); } plugin.app.metadataCache.trigger("metadata-menu:fields-changed", { file, changes }); } // src/fields/base/BaseModal.ts var BaseValueModal = class extends import_obsidian3.Modal { constructor() { super(...arguments); this.saved = false; } onOpen() { this.contentEl.setAttr("id", `field_${this.managedField.id}_update_modal`); this.containerEl.onkeydown = async (e) => { if (e.key == "Enter" && e.altKey) { e.preventDefault(); this.save(); } if (e.key === "Escape" && e.altKey) { this.close(); } }; this.managedField.plugin.app.workspace.trigger("metadata-menu:field-update-modal-built", this); } async onClose() { var _a; if (!this.saved) (_a = this.managedField.previousModal) == null ? void 0 : _a.open(); this.saved = false; } async save() { this.saved = true; this.managedField.save(); } }; function basicModal(managedField, plugin) { return class BasicValueModal extends BaseValueModal { constructor(...rest) { super(plugin.app); this.managedField = managedField; this.titleEl.setText(this.managedField.name); } }; } function basicSuggestModal(managedField, plugin) { return class BasicValueSuggestModal extends import_obsidian3.SuggestModal { constructor(...rest) { super(plugin.app); this.managedField = managedField; } getSuggestions(query) { throw new Error("Method not implemented."); } renderSuggestion(value, el) { throw new Error("Method not implemented."); } onChooseSuggestion(item, evt) { throw new Error("Method not implemented."); } }; } function basicFuzzySuggestModal(managedField, plugin) { return class BasicValueSuggestModal extends import_obsidian3.FuzzySuggestModal { constructor(...rest) { super(plugin.app); this.managedField = managedField; } getItems() { throw new Error("Method not implemented."); } getItemText(item) { throw new Error("Method not implemented."); } onChooseItem(item, evt) { throw new Error("Method not implemented."); } }; } var MultiTargetModificationConfirmModal = class extends import_obsidian3.Modal { constructor(managedField) { super(managedField.plugin.app); this.managedField = managedField; this.containerEl.classList.add("metadata-menu", "confirm-modal"); } async onOpen() { var _a, _b; this.titleEl.innerHTML = `Change ${this.managedField.name} current values`; this.contentEl.createEl("hr"); this.contentEl.createEl("span", { text: "New value: " }); this.contentEl.createEl("span", { cls: "field-value", text: `${this.managedField.value}` }); this.contentEl.createEl("hr"); this.contentEl.createDiv({ text: `Target file(s) (${this.managedField.target.length}):` }); const targetsContainer = this.contentEl.createDiv(); const targets = []; for (const file of this.managedField.target) { const eF = await getExistingFieldForIndexedPath(this.managedField.plugin, file, this.managedField.indexedPath || this.managedField.id); targets.push({ filePath: file.path, fileName: file.basename, existingField: eF }); } for (const target of targets) { const targetContainer = targetsContainer.createDiv({ cls: "target-container" }); const locationContainer = targetContainer.createDiv({ cls: "location-container" }); locationContainer.createSpan({ cls: "file-name", text: target.fileName }); const positionIconContainer = locationContainer.createSpan({ cls: "position-icon", text: target.fileName }); if (target.existingField) { const position = target.existingField.position; (0, import_obsidian3.setIcon)(positionIconContainer, positionIcon[position]); positionIconContainer.ariaLabel = `${this.managedField.name} current section: ${position}`; } else { (0, import_obsidian3.setIcon)(positionIconContainer, "circle-slash"); positionIconContainer.ariaLabel = `${this.managedField.name} hasn't been found in this file`; } const lineNumber = (_a = target.existingField) == null ? void 0 : _a.lineNumber; const lineNumberDisplay = locationContainer.createSpan({ cls: "line-number", text: lineNumber ? `(${lineNumber})` : "" }); if (lineNumber) lineNumberDisplay.ariaLabel = `${this.managedField.name} current line: ${lineNumber}`; const currentValueContainer = targetContainer.createDiv({ cls: "current-value", text: getValueDisplay(target.existingField) }); if (!((_b = target.existingField) == null ? void 0 : _b.value)) currentValueContainer.addClass("empty-or-missing"); } const footer = this.contentEl.createDiv({ cls: "footer-container" }); new import_obsidian3.ButtonComponent(footer).setButtonText("Confirm").setWarning().onClick(() => { for (const target of targets) { postValues( this.managedField.plugin, [{ indexedPath: this.managedField.id, payload: { value: this.managedField.value } }], target.filePath, this.managedField.lineNumber || -1, this.managedField.asList, this.managedField.asBlockquote ); } this.close(); }); } }; // src/utils/modals.ts var cleanActions = (container, actionClass) => { const actions25 = container.querySelector(actionClass); if (actions25) actions25.remove(); }; // src/fields/models/Input.ts var Base = class { constructor() { this.type = "Input"; this.tagName = "single"; this.icon = "pencil"; this.tooltip = "Accepts any value"; this.colorClass = "single"; } }; var DefaultOptions = {}; function settingsModal(Base25) { return class InputSettingModal extends Base25 { constructor() { super(...arguments); this.createSettingContainer = () => { const container = this.optionsContainer; this.field.options.template; container.createEl("span", { text: "Template", cls: "label" }); const templateContainer = container.createDiv({ cls: "field-container" }); this.templateValue = new import_obsidian4.TextAreaComponent(templateContainer); const templateValue = this.templateValue; templateValue.inputEl.cols = 50; templateValue.inputEl.rows = 4; templateValue.inputEl.addClass("full-width"); templateValue.setValue(this.field.options.template || ""); templateValue.onChange((value) => { this.field.options.template = value; }); templateValue.inputEl.setAttr("id", "template-input"); }; } validateOptions() { return true; } }; } function valueModal(managedField, plugin) { const base = basicModal(managedField, plugin); return class ValueModal extends base { constructor(...rest) { super(plugin.app); this.templateValues = {}; this.managedField = managedField; this.titleEl.setText(`Change Value for <${this.managedField.name}>`); this.build(); } build() { const options2 = this.managedField.options; if (options2.template) { const templateFieldRegex = new RegExp(`\\{\\{(?[^\\}]+?)\\}\\}`, "gu"); const tF = options2.template.matchAll(templateFieldRegex); let next = tF.next(); while (!next.done) { if (next.value.groups) { const value = next.value.groups.field; const [name, optionsString] = value.split(/:(.*)/s).map((v) => v.trim()); this.templateValues[name] = ""; if (optionsString) { try { const selectOptions = JSON.parse(optionsString); this.buildTemplateSelectItem(options2.template, this.contentEl.createDiv({ cls: "field-container" }), name, selectOptions); } catch ({ name: errorName, message }) { const notice = `{{${name}}} field definition is not a valid JSON in <${this.managedField.name}> ${this.managedField.fileClassName ? this.managedField.fileClassName : "Metadata Menu"} settings`; if (errorName === "SyntaxError") new import_obsidian4.Notice(notice, 5e3); } } else { this.buildTemplateInputItem(options2.template, this.contentEl.createDiv({ cls: "field-container" }), name); } } next = tF.next(); } this.contentEl.createDiv({ text: "Result preview" }); this.buildResultPreview(this.contentEl.createDiv({ cls: "field-container" })); } else { this.buildInputEl(this.contentEl.createDiv({ cls: "field-container" })); } cleanActions(this.contentEl, ".footer-actions"); this.buildFooterBtn(); this.containerEl.addClass("metadata-menu"); } renderValue(template) { let renderedString = template.slice(); Object.keys(this.templateValues).forEach((k) => { const fieldRegex = new RegExp(`\\{\\{${k.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(:[^\\}]*)?\\}\\}`, "u"); renderedString = renderedString.replace(fieldRegex, this.templateValues[k]); }); this.renderedValue.setValue(renderedString.replaceAll("\n", ", ")); this.managedField.value = renderedString.replaceAll("\n", ", "); } buildTemplateInputItem(template, fieldContainer, name) { fieldContainer.createDiv({ cls: "label", text: name }); const input = new import_obsidian4.TextComponent(fieldContainer); input.inputEl.addClass("with-label"); input.inputEl.addClass("full-width"); input.setPlaceholder(`Enter a value for ${name}`); input.onChange((value) => { this.templateValues[name] = value; this.renderValue(template); }); } buildTemplateSelectItem(template, fieldContainer, name, options2) { fieldContainer.createDiv({ text: name, cls: "label" }); fieldContainer.createDiv({ cls: "spacer" }); const selectEl = new import_obsidian4.DropdownComponent(fieldContainer); selectEl.addOption("", "--select--"); options2.forEach((o) => selectEl.addOption(o, o)); selectEl.onChange((value) => { this.templateValues[name] = value; this.renderValue(template); }); } buildResultPreview(fieldContainer) { this.renderedValue = new import_obsidian4.TextAreaComponent(fieldContainer); this.renderedValue.inputEl.rows = 3; this.renderedValue.inputEl.addClass("full-width"); if (isSingleTargeted(this.managedField)) { this.renderedValue.setValue(this.managedField.value); } else { this.renderedValue.setPlaceholder("Multiple values"); } this.renderedValue.setValue(this.managedField.value); this.renderedValue.onChange((value) => this.managedField.value = `${value}`); } buildInputEl(container) { const inputEl = new import_obsidian4.TextAreaComponent(container); inputEl.inputEl.rows = 3; inputEl.inputEl.focus(); inputEl.inputEl.addClass("full-width"); if (isSingleTargeted(this.managedField)) { inputEl.setValue(`${this.managedField.value || ""}`); } else { inputEl.setPlaceholder("Multiple values"); } inputEl.onChange((value) => this.managedField.value = `${value}`); } buildFooterBtn() { const buttonContainer = this.containerEl.createDiv({ cls: "footer-actions" }); buttonContainer.createDiv({ cls: "spacer" }); const infoContainer = buttonContainer.createDiv({ cls: "info" }); infoContainer.setText("Alt+Enter to save"); const confirmButton = new import_obsidian4.ButtonComponent(buttonContainer); confirmButton.setIcon("checkmark"); confirmButton.onClick(async () => { this.save(); this.close(); }); const cancelButton = new import_obsidian4.ButtonComponent(buttonContainer); cancelButton.setIcon("cross"); cancelButton.onClick(() => { this.close(); }); this.modalEl.appendChild(buttonContainer); } async save() { this.saved = true; this.managedField.save(); this.close(); } }; } function valueString(managedField) { return baseGetValueString(managedField); } function displayValue(managedField, container, onClicked = () => { }) { return baseDisplayValue(managedField, container, onClicked); } function createDvField(managedField, dv, p, fieldContainer, attrs = {}) { var _a, _b; attrs.cls = "value-container"; const editBtn = fieldContainer.createEl("button"); const fieldValue = dv.el("span", managedField.value || "", attrs); fieldContainer.appendChild(fieldValue); const spacer = fieldContainer.createDiv({ cls: "spacer-1" }); if ((_a = attrs.options) == null ? void 0 : _a.alwaysOn) spacer.hide(); (0, import_obsidian4.setIcon)(editBtn, getIcon("Input")); if (!((_b = attrs == null ? void 0 : attrs.options) == null ? void 0 : _b.alwaysOn)) { editBtn.hide(); spacer.show(); fieldContainer.onmouseover = () => { editBtn.show(); spacer.hide(); }; fieldContainer.onmouseout = () => { var _a2; editBtn.hide(); if (!((_a2 = attrs.options) == null ? void 0 : _a2.alwaysOn)) spacer.show(); }; } editBtn.onclick = async () => { managedField.openModal(); }; } function actions(plugin, field2, file, location, indexedPath) { const iconName = getIcon(field2.type); const action = async () => { var _a; const eF = await getExistingFieldForIndexedPath2(plugin, file, indexedPath); (_a = fieldValueManager(plugin, field2.id, field2.fileClassName, file, eF, indexedPath)) == null ? void 0 : _a.openModal(); }; if (isSuggest(location)) { location.options.push({ id: `update_${field2.name}`, actionLabel: `Update ${field2.name}`, action, icon: iconName }); } else if (isFieldActions(location)) { location.addOption(`field_${field2.id}_update`, iconName, action, `Update ${field2.name}'s value`); } } function getOptionsStr(field2) { return field2.options.template || ""; } function validateValue(managedField) { return true; } async function enterFieldSetting(settingModal, field2, speed = 100) { var _a; const runner = settingModal.plugin.testRunner; if (((_a = field2.options) == null ? void 0 : _a.template) !== void 0) { settingModal.plugin.testRunner.insertInTextComponent(settingModal.templateValue, field2.options.template); const input = settingModal.containerEl.querySelector("#template-input"); if (!input) return runner.log("ERROR", "Template input not found"); if (!(input.value === settingModal.templateValue.getValue())) return runner.log("ERROR", "Template input error"); } } // src/fields/models/Number.ts var import_obsidian5 = require("obsidian"); var Base2 = class { constructor() { this.type = "Number"; this.tagName = "number"; this.icon = "plus-minus-glyph"; this.tooltip = "Accepts a number"; this.colorClass = "number"; } }; var DefaultOptions2 = {}; function settingsModal2(Base25) { return class SettingModal extends Base25 { constructor() { super(...arguments); this.createSettingContainer = () => { const container = this.optionsContainer; const numberStepValueContainer = container.createDiv({ cls: "field-container" }); numberStepValueContainer.createEl("span", { text: "Step (optional)", cls: "label" }); numberStepValueContainer.createDiv({ cls: "spacer" }); this.numberStepValue = new import_obsidian5.TextComponent(numberStepValueContainer); this.numberStepValue.inputEl.addClass("with-label"); this.numberStepValue.setValue(`${this.field.options.step || ""}`); const numberMinValueContainer = container.createDiv({ cls: "field-container" }); numberMinValueContainer.createEl("span", { text: "Min value (optional)", cls: "label" }); this.numberMinValue = new import_obsidian5.TextComponent(numberMinValueContainer); this.numberMinValue.inputEl.addClass("full-width"); this.numberMinValue.inputEl.addClass("with-label"); this.numberMinValue.setValue(`${this.field.options.min || ""}`); const numberMaxValueContainer = container.createDiv({ cls: "field-container" }); numberMaxValueContainer.createEl("span", { text: "Max value (optional)", cls: "label" }); this.numberMaxValue = new import_obsidian5.TextComponent(numberMaxValueContainer); this.numberMaxValue.inputEl.addClass("full-width"); this.numberMaxValue.inputEl.addClass("with-label"); this.numberMaxValue.setValue(`${this.field.options.max || ""}`); this.numberStepValue.onChange((value) => { this.field.options.step = parseFloat(value); removeValidationError(this.numberStepValue); }); this.numberMinValue.onChange((value) => { this.field.options.min = parseFloat(value); removeValidationError(this.numberMinValue); }); this.numberMaxValue.onChange((value) => { this.field.options.max = parseFloat(value); removeValidationError(this.numberMaxValue); }); }; } validateOptions() { return true; } }; } function valueModal2(managedField, plugin) { const base = basicModal(managedField, plugin); return class ValueModal extends base { constructor(...rest) { super(); this.containerEl.addClass("metadata-menu"); this.value = managedField.value; this.buildInputEl(); } decrement(numberInput) { const { step } = this.managedField.options; const fStep = parseFloat(step); const fValue = parseFloat(numberInput.getValue()) || 0; if (!isNaN(fStep)) { const newValue = (fValue - fStep).toString(); this.managedField.value = newValue; numberInput.setValue((fValue - fStep).toString()); } else { const newValue = (fValue - 1).toString(); this.managedField.value = newValue; numberInput.setValue((fValue - 1).toString()); } } increment(numberInput) { const { step } = this.managedField.options; const fStep = parseFloat(step); const fValue = parseFloat(numberInput.getValue()) || 0; if (!isNaN(fStep)) { const newValue = (fValue + fStep).toString(); this.managedField.value = newValue; numberInput.setValue(newValue); } else { const newValue = (fValue + 1).toString(); this.managedField.value = newValue; numberInput.setValue((fValue + 1).toString()); } } toggleButtonsState(minusBtn, plusBtn, numberInput) { minusBtn.setDisabled(!canDecrement(this.managedField)); plusBtn.setDisabled(!canIncrement(this.managedField)); if (canDecrement(this.managedField)) { minusBtn.setCta(); } else { minusBtn.removeCta(); } if (canIncrement(this.managedField)) { plusBtn.setCta(); } else { plusBtn.removeCta(); } } buildInputEl() { const { step } = this.managedField.options; cleanActions(this.contentEl, ".field-container"); const fieldContainer = this.contentEl.createEl("div", { cls: "field-container" }); this.numberInput = new import_obsidian5.TextComponent(fieldContainer); const numberInput = this.numberInput; numberInput.inputEl.focus(); numberInput.setValue(`${this.value || ""}`); const minusBtn = new import_obsidian5.ButtonComponent(fieldContainer); minusBtn.setButtonText(`- ${!!step ? step : 1}`); minusBtn.setDisabled(!canDecrement(this.managedField)); const plusBtn = new import_obsidian5.ButtonComponent(fieldContainer); plusBtn.setButtonText(`+ ${!!step ? step : 1}`); plusBtn.setDisabled(!canIncrement(this.managedField)); fieldContainer.createDiv({ cls: "spacer" }); this.buildSaveBtn(fieldContainer); cleanActions(this.contentEl, ".field-error"); this.errorField = this.contentEl.createEl("div", { cls: "field-error" }); this.errorField.hide(); this.toggleButtonsState(minusBtn, plusBtn, numberInput); numberInput.onChange((value) => { numberInput.inputEl.removeClass("is-invalid"); this.managedField.value = value; this.errorField.hide(); this.errorField.setText(""); this.toggleButtonsState(minusBtn, plusBtn, numberInput); }); plusBtn.onClick((e) => { e.preventDefault(); this.increment(numberInput); this.toggleButtonsState(minusBtn, plusBtn, numberInput); }); minusBtn.onClick((e) => { e.preventDefault(); this.decrement(numberInput); this.toggleButtonsState(minusBtn, plusBtn, numberInput); }); } buildSaveBtn(fieldContainer) { fieldContainer.createDiv({ cls: "spacer" }); const infoContainer = fieldContainer.createDiv({ cls: "info" }); infoContainer.setText("Alt+Enter to save"); const saveBtn = new import_obsidian5.ButtonComponent(fieldContainer); saveBtn.setIcon("checkmark"); saveBtn.onClick(() => { this.save(); }); } async save() { if (!validateValue2(this.managedField)) { const { min: min2, max: max2 } = this.managedField.options; this.errorField.show(); this.errorField.setText(`value must be numeric${min2 ? " and >= " + min2 : ""} ${max2 ? " and <= " + max2 : ""}`); this.numberInput.inputEl.setAttr("class", "is-invalid"); return; } this.saved = true; managedField.save(); this.close(); } }; } function valueString2(managedField) { return baseGetValueString(managedField); } function displayValue2(managedField, container, onClicked = () => { }) { return baseDisplayValue(managedField, container, onClicked); } function createDvField2(managedField, dv, p, fieldContainer, attrs = {}) { var _a, _b; attrs.cls = "value-container"; const editBtn = fieldContainer.createEl("button"); const fieldValue = dv.el("span", managedField.value || "", attrs); fieldContainer.appendChild(fieldValue); const spacer = fieldContainer.createDiv({ cls: "spacer-1" }); if ((_a = attrs.options) == null ? void 0 : _a.alwaysOn) spacer.hide(); (0, import_obsidian5.setIcon)(editBtn, getIcon("Number")); if (!((_b = attrs == null ? void 0 : attrs.options) == null ? void 0 : _b.alwaysOn)) { editBtn.hide(); spacer.show(); fieldContainer.onmouseover = () => { editBtn.show(); spacer.hide(); }; fieldContainer.onmouseout = () => { var _a2; editBtn.hide(); if (!((_a2 = attrs.options) == null ? void 0 : _a2.alwaysOn)) spacer.show(); }; } editBtn.onclick = async () => { managedField.openModal(); }; } function actions2(plugin, field2, file, location, indexedPath) { const iconName = getIcon(field2.type); const name = field2.name; const { step } = field2.options; const action = async () => { var _a; const eF = await getExistingFieldForIndexedPath2(plugin, file, indexedPath); (_a = fieldValueManager(plugin, field2.id, field2.fileClassName, file, eF, indexedPath)) == null ? void 0 : _a.openModal(); }; const increase = async () => { const eF = await getExistingFieldForIndexedPath2(plugin, file, indexedPath); const fieldVM = fieldValueManager(plugin, field2.id, field2.fileClassName, file, eF, indexedPath); if (fieldVM) await applyStep(fieldVM, "increase"); }; const decrease = async () => { const eF = await getExistingFieldForIndexedPath2(plugin, file, indexedPath); const fieldVM = fieldValueManager(plugin, field2.id, field2.fileClassName, file, eF, indexedPath); if (fieldVM) await applyStep(fieldVM, "decrease"); }; if (isSuggest(location)) { location.options.push({ id: `update_${name}`, actionLabel: `Update ${name}`, action, icon: iconName }); } else if (isFieldActions(location)) { if (step) { location.addOption(`field_${field2.id}_decrease`, "minus-square", decrease, `Decrease ${name} by ${step}`); location.addOption(`field_${field2.id}_increase`, "plus-square", increase, `Increase ${name} by ${step}`); } location.addOption(`field_${field2.id}_update`, iconName, action, `Update ${name}'s value`); } ; } function getOptionsStr2(field2) { const options2 = []; Object.keys(field2.options).forEach((k) => { if (field2.options[k]) options2.push(`${k}: ${field2.options[k]}`); }); return options2.join(" | "); } function validateValue2(managedField) { const { min: min2, max: max2 } = managedField.options; if (!min2 || !max2) return true; const fMin = parseFloat(`${min2}`); const fMax = parseFloat(`${max2}`); const fValue = parseFloat(`${managedField.value}`); return !isNaN(fValue) && (isNaN(fMin) || fValue >= fMin) && (isNaN(fMax) || fValue <= fMax); } async function applyStep(managedField, direction) { const { min: min2, max: max2, step } = managedField.options; const fMin = parseFloat(`${min2}`); const fMax = parseFloat(`${max2}`); const fStep = parseFloat(`${step}`); const fValue = parseFloat(managedField.value) || 0; switch (direction) { case "decrease": if (!isNaN(fMin) && !isNaN(fStep) && fValue - fStep >= fMin) managedField.save((fValue - fStep).toString()); break; case "increase": if (!isNaN(fMax) && !isNaN(fStep) && fValue + fStep <= fMax) managedField.save((fValue + fStep).toString()); default: break; } } function canDecrement(managedField) { const { step, min: min2 } = managedField.options; const fStep = parseFloat(`${step}`); const fMin = parseFloat(`${min2}`); return !//isNaN(parseFloat(value)) || (!isNaN(fMin) && (!isNaN(fStep) && ((parseFloat(`${managedField.value}`) || 0) - fStep < fMin || (parseFloat(`${managedField.value}`) || 0) - 1 < fMin))); } function canIncrement(managedField) { const { step, max: max2 } = managedField.options; const fStep = parseFloat(`${step}`); const fMax = parseFloat(`${max2}`); return !//isNaN(parseFloat(value)) || (!isNaN(fMax) && (!isNaN(fStep) && ((parseFloat(`${managedField.value}`) || 0) + fStep > fMax || (parseFloat(`${managedField.value}`) || 0) + 1 > fMax))); } async function enterFieldSetting2(settingModal, field2, speed = 100) { if (field2.options.min || field2.options.min === 0) settingModal.plugin.testRunner.insertInTextComponent(settingModal.numberMinValue, `${field2.options.min}`); if (field2.options.max || field2.options.max === 0) settingModal.plugin.testRunner.insertInTextComponent(settingModal.numberMaxValue, `${field2.options.max}`); if (field2.options.step || field2.options.step === 0) settingModal.plugin.testRunner.insertInTextComponent(settingModal.numberStepValue, `${field2.options.step}`); } // src/fields/models/abstractModels/AbstractList.ts var import_obsidian8 = require("obsidian"); // src/suggester/FileSuggester.ts var import_obsidian7 = require("obsidian"); // src/suggester/suggest.ts var import_obsidian6 = require("obsidian"); // node_modules/@popperjs/core/lib/enums.js var top = "top"; var bottom = "bottom"; var right = "right"; var left = "left"; var auto = "auto"; var basePlacements = [top, bottom, right, left]; var start = "start"; var end = "end"; var clippingParents = "clippingParents"; var viewport = "viewport"; var popper = "popper"; var reference = "reference"; var variationPlacements = /* @__PURE__ */ basePlacements.reduce(function(acc, placement) { return acc.concat([placement + "-" + start, placement + "-" + end]); }, []); var placements = /* @__PURE__ */ [].concat(basePlacements, [auto]).reduce(function(acc, placement) { return acc.concat([placement, placement + "-" + start, placement + "-" + end]); }, []); var beforeRead = "beforeRead"; var read = "read"; var afterRead = "afterRead"; var beforeMain = "beforeMain"; var main = "main"; var afterMain = "afterMain"; var beforeWrite = "beforeWrite"; var write = "write"; var afterWrite = "afterWrite"; var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite]; // node_modules/@popperjs/core/lib/dom-utils/getNodeName.js function getNodeName(element) { return element ? (element.nodeName || "").toLowerCase() : null; } // node_modules/@popperjs/core/lib/dom-utils/getWindow.js function getWindow(node) { if (node == null) { return window; } if (node.toString() !== "[object Window]") { var ownerDocument = node.ownerDocument; return ownerDocument ? ownerDocument.defaultView || window : window; } return node; } // node_modules/@popperjs/core/lib/dom-utils/instanceOf.js function isElement(node) { var OwnElement = getWindow(node).Element; return node instanceof OwnElement || node instanceof Element; } function isHTMLElement(node) { var OwnElement = getWindow(node).HTMLElement; return node instanceof OwnElement || node instanceof HTMLElement; } function isShadowRoot(node) { if (typeof ShadowRoot === "undefined") { return false; } var OwnElement = getWindow(node).ShadowRoot; return node instanceof OwnElement || node instanceof ShadowRoot; } // node_modules/@popperjs/core/lib/modifiers/applyStyles.js function applyStyles(_ref) { var state = _ref.state; Object.keys(state.elements).forEach(function(name) { var style = state.styles[name] || {}; var attributes = state.attributes[name] || {}; var element = state.elements[name]; if (!isHTMLElement(element) || !getNodeName(element)) { return; } Object.assign(element.style, style); Object.keys(attributes).forEach(function(name2) { var value = attributes[name2]; if (value === false) { element.removeAttribute(name2); } else { element.setAttribute(name2, value === true ? "" : value); } }); }); } function effect(_ref2) { var state = _ref2.state; var initialStyles = { popper: { position: state.options.strategy, left: "0", top: "0", margin: "0" }, arrow: { position: "absolute" }, reference: {} }; Object.assign(state.elements.popper.style, initialStyles.popper); state.styles = initialStyles; if (state.elements.arrow) { Object.assign(state.elements.arrow.style, initialStyles.arrow); } return function() { Object.keys(state.elements).forEach(function(name) { var element = state.elements[name]; var attributes = state.attributes[name] || {}; var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); var style = styleProperties.reduce(function(style2, property) { style2[property] = ""; return style2; }, {}); if (!isHTMLElement(element) || !getNodeName(element)) { return; } Object.assign(element.style, style); Object.keys(attributes).forEach(function(attribute) { element.removeAttribute(attribute); }); }); }; } var applyStyles_default = { name: "applyStyles", enabled: true, phase: "write", fn: applyStyles, effect, requires: ["computeStyles"] }; // node_modules/@popperjs/core/lib/utils/getBasePlacement.js function getBasePlacement(placement) { return placement.split("-")[0]; } // node_modules/@popperjs/core/lib/utils/math.js var max = Math.max; var min = Math.min; var round = Math.round; // node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js function getBoundingClientRect(element, includeScale) { if (includeScale === void 0) { includeScale = false; } var rect = element.getBoundingClientRect(); var scaleX = 1; var scaleY = 1; if (isHTMLElement(element) && includeScale) { var offsetHeight = element.offsetHeight; var offsetWidth = element.offsetWidth; if (offsetWidth > 0) { scaleX = round(rect.width) / offsetWidth || 1; } if (offsetHeight > 0) { scaleY = round(rect.height) / offsetHeight || 1; } } return { width: rect.width / scaleX, height: rect.height / scaleY, top: rect.top / scaleY, right: rect.right / scaleX, bottom: rect.bottom / scaleY, left: rect.left / scaleX, x: rect.left / scaleX, y: rect.top / scaleY }; } // node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js function getLayoutRect(element) { var clientRect = getBoundingClientRect(element); var width = element.offsetWidth; var height = element.offsetHeight; if (Math.abs(clientRect.width - width) <= 1) { width = clientRect.width; } if (Math.abs(clientRect.height - height) <= 1) { height = clientRect.height; } return { x: element.offsetLeft, y: element.offsetTop, width, height }; } // node_modules/@popperjs/core/lib/dom-utils/contains.js function contains(parent, child) { var rootNode = child.getRootNode && child.getRootNode(); if (parent.contains(child)) { return true; } else if (rootNode && isShadowRoot(rootNode)) { var next = child; do { if (next && parent.isSameNode(next)) { return true; } next = next.parentNode || next.host; } while (next); } return false; } // node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js function getComputedStyle2(element) { return getWindow(element).getComputedStyle(element); } // node_modules/@popperjs/core/lib/dom-utils/isTableElement.js function isTableElement(element) { return ["table", "td", "th"].indexOf(getNodeName(element)) >= 0; } // node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js function getDocumentElement(element) { return ((isElement(element) ? element.ownerDocument : ( // $FlowFixMe[prop-missing] element.document )) || window.document).documentElement; } // node_modules/@popperjs/core/lib/dom-utils/getParentNode.js function getParentNode(element) { if (getNodeName(element) === "html") { return element; } return ( // this is a quicker (but less type safe) way to save quite some bytes from the bundle // $FlowFixMe[incompatible-return] // $FlowFixMe[prop-missing] element.assignedSlot || // step into the shadow DOM of the parent of a slotted node element.parentNode || // DOM Element detected (isShadowRoot(element) ? element.host : null) || // ShadowRoot detected // $FlowFixMe[incompatible-call]: HTMLElement is a Node getDocumentElement(element) ); } // node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js function getTrueOffsetParent(element) { if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837 getComputedStyle2(element).position === "fixed") { return null; } return element.offsetParent; } function getContainingBlock(element) { var isFirefox = navigator.userAgent.toLowerCase().indexOf("firefox") !== -1; var isIE = navigator.userAgent.indexOf("Trident") !== -1; if (isIE && isHTMLElement(element)) { var elementCss = getComputedStyle2(element); if (elementCss.position === "fixed") { return null; } } var currentNode = getParentNode(element); if (isShadowRoot(currentNode)) { currentNode = currentNode.host; } while (isHTMLElement(currentNode) && ["html", "body"].indexOf(getNodeName(currentNode)) < 0) { var css = getComputedStyle2(currentNode); if (css.transform !== "none" || css.perspective !== "none" || css.contain === "paint" || ["transform", "perspective"].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === "filter" || isFirefox && css.filter && css.filter !== "none") { return currentNode; } else { currentNode = currentNode.parentNode; } } return null; } function getOffsetParent(element) { var window2 = getWindow(element); var offsetParent = getTrueOffsetParent(element); while (offsetParent && isTableElement(offsetParent) && getComputedStyle2(offsetParent).position === "static") { offsetParent = getTrueOffsetParent(offsetParent); } if (offsetParent && (getNodeName(offsetParent) === "html" || getNodeName(offsetParent) === "body" && getComputedStyle2(offsetParent).position === "static")) { return window2; } return offsetParent || getContainingBlock(element) || window2; } // node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js function getMainAxisFromPlacement(placement) { return ["top", "bottom"].indexOf(placement) >= 0 ? "x" : "y"; } // node_modules/@popperjs/core/lib/utils/within.js function within(min2, value, max2) { return max(min2, min(value, max2)); } function withinMaxClamp(min2, value, max2) { var v = within(min2, value, max2); return v > max2 ? max2 : v; } // node_modules/@popperjs/core/lib/utils/getFreshSideObject.js function getFreshSideObject() { return { top: 0, right: 0, bottom: 0, left: 0 }; } // node_modules/@popperjs/core/lib/utils/mergePaddingObject.js function mergePaddingObject(paddingObject) { return Object.assign({}, getFreshSideObject(), paddingObject); } // node_modules/@popperjs/core/lib/utils/expandToHashMap.js function expandToHashMap(value, keys) { return keys.reduce(function(hashMap, key) { hashMap[key] = value; return hashMap; }, {}); } // node_modules/@popperjs/core/lib/modifiers/arrow.js var toPaddingObject = function toPaddingObject2(padding, state) { padding = typeof padding === "function" ? padding(Object.assign({}, state.rects, { placement: state.placement })) : padding; return mergePaddingObject(typeof padding !== "number" ? padding : expandToHashMap(padding, basePlacements)); }; function arrow(_ref) { var _state$modifiersData$; var state = _ref.state, name = _ref.name, options2 = _ref.options; var arrowElement = state.elements.arrow; var popperOffsets2 = state.modifiersData.popperOffsets; var basePlacement = getBasePlacement(state.placement); var axis = getMainAxisFromPlacement(basePlacement); var isVertical = [left, right].indexOf(basePlacement) >= 0; var len = isVertical ? "height" : "width"; if (!arrowElement || !popperOffsets2) { return; } var paddingObject = toPaddingObject(options2.padding, state); var arrowRect = getLayoutRect(arrowElement); var minProp = axis === "y" ? top : left; var maxProp = axis === "y" ? bottom : right; var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets2[axis] - state.rects.popper[len]; var startDiff = popperOffsets2[axis] - state.rects.reference[axis]; var arrowOffsetParent = getOffsetParent(arrowElement); var clientSize = arrowOffsetParent ? axis === "y" ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0; var centerToReference = endDiff / 2 - startDiff / 2; var min2 = paddingObject[minProp]; var max2 = clientSize - arrowRect[len] - paddingObject[maxProp]; var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference; var offset2 = within(min2, center, max2); var axisProp = axis; state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset2, _state$modifiersData$.centerOffset = offset2 - center, _state$modifiersData$); } function effect2(_ref2) { var state = _ref2.state, options2 = _ref2.options; var _options$element = options2.element, arrowElement = _options$element === void 0 ? "[data-popper-arrow]" : _options$element; if (arrowElement == null) { return; } if (typeof arrowElement === "string") { arrowElement = state.elements.popper.querySelector(arrowElement); if (!arrowElement) { return; } } if (true) { if (!isHTMLElement(arrowElement)) { console.error(['Popper: "arrow" element must be an HTMLElement (not an SVGElement).', "To use an SVG arrow, wrap it in an HTMLElement that will be used as", "the arrow."].join(" ")); } } if (!contains(state.elements.popper, arrowElement)) { if (true) { console.error(['Popper: "arrow" modifier\'s `element` must be a child of the popper', "element."].join(" ")); } return; } state.elements.arrow = arrowElement; } var arrow_default = { name: "arrow", enabled: true, phase: "main", fn: arrow, effect: effect2, requires: ["popperOffsets"], requiresIfExists: ["preventOverflow"] }; // node_modules/@popperjs/core/lib/utils/getVariation.js function getVariation(placement) { return placement.split("-")[1]; } // node_modules/@popperjs/core/lib/modifiers/computeStyles.js var unsetSides = { top: "auto", right: "auto", bottom: "auto", left: "auto" }; function roundOffsetsByDPR(_ref) { var x = _ref.x, y = _ref.y; var win = window; var dpr = win.devicePixelRatio || 1; return { x: round(x * dpr) / dpr || 0, y: round(y * dpr) / dpr || 0 }; } function mapToStyles(_ref2) { var _Object$assign2; var popper2 = _ref2.popper, popperRect = _ref2.popperRect, placement = _ref2.placement, variation = _ref2.variation, offsets = _ref2.offsets, position = _ref2.position, gpuAcceleration = _ref2.gpuAcceleration, adaptive = _ref2.adaptive, roundOffsets = _ref2.roundOffsets, isFixed = _ref2.isFixed; var _offsets$x = offsets.x, x = _offsets$x === void 0 ? 0 : _offsets$x, _offsets$y = offsets.y, y = _offsets$y === void 0 ? 0 : _offsets$y; var _ref3 = typeof roundOffsets === "function" ? roundOffsets({ x, y }) : { x, y }; x = _ref3.x; y = _ref3.y; var hasX = offsets.hasOwnProperty("x"); var hasY = offsets.hasOwnProperty("y"); var sideX = left; var sideY = top; var win = window; if (adaptive) { var offsetParent = getOffsetParent(popper2); var heightProp = "clientHeight"; var widthProp = "clientWidth"; if (offsetParent === getWindow(popper2)) { offsetParent = getDocumentElement(popper2); if (getComputedStyle2(offsetParent).position !== "static" && position === "absolute") { heightProp = "scrollHeight"; widthProp = "scrollWidth"; } } offsetParent = offsetParent; if (placement === top || (placement === left || placement === right) && variation === end) { sideY = bottom; var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : ( // $FlowFixMe[prop-missing] offsetParent[heightProp] ); y -= offsetY - popperRect.height; y *= gpuAcceleration ? 1 : -1; } if (placement === left || (placement === top || placement === bottom) && variation === end) { sideX = right; var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : ( // $FlowFixMe[prop-missing] offsetParent[widthProp] ); x -= offsetX - popperRect.width; x *= gpuAcceleration ? 1 : -1; } } var commonStyles = Object.assign({ position }, adaptive && unsetSides); var _ref4 = roundOffsets === true ? roundOffsetsByDPR({ x, y }) : { x, y }; x = _ref4.x; y = _ref4.y; if (gpuAcceleration) { var _Object$assign; return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? "0" : "", _Object$assign[sideX] = hasX ? "0" : "", _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign)); } return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : "", _Object$assign2[sideX] = hasX ? x + "px" : "", _Object$assign2.transform = "", _Object$assign2)); } function computeStyles(_ref5) { var state = _ref5.state, options2 = _ref5.options; var _options$gpuAccelerat = options2.gpuAcceleration, gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat, _options$adaptive = options2.adaptive, adaptive = _options$adaptive === void 0 ? true : _options$adaptive, _options$roundOffsets = options2.roundOffsets, roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets; if (true) { var transitionProperty = getComputedStyle2(state.elements.popper).transitionProperty || ""; if (adaptive && ["transform", "top", "right", "bottom", "left"].some(function(property) { return transitionProperty.indexOf(property) >= 0; })) { console.warn(["Popper: Detected CSS transitions on at least one of the following", 'CSS properties: "transform", "top", "right", "bottom", "left".', "\n\n", 'Disable the "computeStyles" modifier\'s `adaptive` option to allow', "for smooth transitions, or remove these properties from the CSS", "transition declaration on the popper element if only transitioning", "opacity or background-color for example.", "\n\n", "We recommend using the popper element as a wrapper around an inner", "element that can have any CSS property transitioned for animations."].join(" ")); } } var commonStyles = { placement: getBasePlacement(state.placement), variation: getVariation(state.placement), popper: state.elements.popper, popperRect: state.rects.popper, gpuAcceleration, isFixed: state.options.strategy === "fixed" }; if (state.modifiersData.popperOffsets != null) { state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, { offsets: state.modifiersData.popperOffsets, position: state.options.strategy, adaptive, roundOffsets }))); } if (state.modifiersData.arrow != null) { state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, { offsets: state.modifiersData.arrow, position: "absolute", adaptive: false, roundOffsets }))); } state.attributes.popper = Object.assign({}, state.attributes.popper, { "data-popper-placement": state.placement }); } var computeStyles_default = { name: "computeStyles", enabled: true, phase: "beforeWrite", fn: computeStyles, data: {} }; // node_modules/@popperjs/core/lib/modifiers/eventListeners.js var passive = { passive: true }; function effect3(_ref) { var state = _ref.state, instance = _ref.instance, options2 = _ref.options; var _options$scroll = options2.scroll, scroll = _options$scroll === void 0 ? true : _options$scroll, _options$resize = options2.resize, resize = _options$resize === void 0 ? true : _options$resize; var window2 = getWindow(state.elements.popper); var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper); if (scroll) { scrollParents.forEach(function(scrollParent) { scrollParent.addEventListener("scroll", instance.update, passive); }); } if (resize) { window2.addEventListener("resize", instance.update, passive); } return function() { if (scroll) { scrollParents.forEach(function(scrollParent) { scrollParent.removeEventListener("scroll", instance.update, passive); }); } if (resize) { window2.removeEventListener("resize", instance.update, passive); } }; } var eventListeners_default = { name: "eventListeners", enabled: true, phase: "write", fn: function fn() { }, effect: effect3, data: {} }; // node_modules/@popperjs/core/lib/utils/getOppositePlacement.js var hash = { left: "right", right: "left", bottom: "top", top: "bottom" }; function getOppositePlacement(placement) { return placement.replace(/left|right|bottom|top/g, function(matched) { return hash[matched]; }); } // node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js var hash2 = { start: "end", end: "start" }; function getOppositeVariationPlacement(placement) { return placement.replace(/start|end/g, function(matched) { return hash2[matched]; }); } // node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js function getWindowScroll(node) { var win = getWindow(node); var scrollLeft = win.pageXOffset; var scrollTop = win.pageYOffset; return { scrollLeft, scrollTop }; } // node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js function getWindowScrollBarX(element) { return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft; } // node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js function getViewportRect(element) { var win = getWindow(element); var html = getDocumentElement(element); var visualViewport = win.visualViewport; var width = html.clientWidth; var height = html.clientHeight; var x = 0; var y = 0; if (visualViewport) { width = visualViewport.width; height = visualViewport.height; if (!/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) { x = visualViewport.offsetLeft; y = visualViewport.offsetTop; } } return { width, height, x: x + getWindowScrollBarX(element), y }; } // node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js function getDocumentRect(element) { var _element$ownerDocumen; var html = getDocumentElement(element); var winScroll = getWindowScroll(element); var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body; var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0); var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0); var x = -winScroll.scrollLeft + getWindowScrollBarX(element); var y = -winScroll.scrollTop; if (getComputedStyle2(body || html).direction === "rtl") { x += max(html.clientWidth, body ? body.clientWidth : 0) - width; } return { width, height, x, y }; } // node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js function isScrollParent(element) { var _getComputedStyle = getComputedStyle2(element), overflow = _getComputedStyle.overflow, overflowX = _getComputedStyle.overflowX, overflowY = _getComputedStyle.overflowY; return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX); } // node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js function getScrollParent(node) { if (["html", "body", "#document"].indexOf(getNodeName(node)) >= 0) { return node.ownerDocument.body; } if (isHTMLElement(node) && isScrollParent(node)) { return node; } return getScrollParent(getParentNode(node)); } // node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js function listScrollParents(element, list) { var _element$ownerDocumen; if (list === void 0) { list = []; } var scrollParent = getScrollParent(element); var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body); var win = getWindow(scrollParent); var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent; var updatedList = list.concat(target); return isBody ? updatedList : ( // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here updatedList.concat(listScrollParents(getParentNode(target))) ); } // node_modules/@popperjs/core/lib/utils/rectToClientRect.js function rectToClientRect(rect) { return Object.assign({}, rect, { left: rect.x, top: rect.y, right: rect.x + rect.width, bottom: rect.y + rect.height }); } // node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js function getInnerBoundingClientRect(element) { var rect = getBoundingClientRect(element); rect.top = rect.top + element.clientTop; rect.left = rect.left + element.clientLeft; rect.bottom = rect.top + element.clientHeight; rect.right = rect.left + element.clientWidth; rect.width = element.clientWidth; rect.height = element.clientHeight; rect.x = rect.left; rect.y = rect.top; return rect; } function getClientRectFromMixedType(element, clippingParent) { return clippingParent === viewport ? rectToClientRect(getViewportRect(element)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent) : rectToClientRect(getDocumentRect(getDocumentElement(element))); } function getClippingParents(element) { var clippingParents2 = listScrollParents(getParentNode(element)); var canEscapeClipping = ["absolute", "fixed"].indexOf(getComputedStyle2(element).position) >= 0; var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element; if (!isElement(clipperElement)) { return []; } return clippingParents2.filter(function(clippingParent) { return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== "body"; }); } function getClippingRect(element, boundary, rootBoundary) { var mainClippingParents = boundary === "clippingParents" ? getClippingParents(element) : [].concat(boundary); var clippingParents2 = [].concat(mainClippingParents, [rootBoundary]); var firstClippingParent = clippingParents2[0]; var clippingRect = clippingParents2.reduce(function(accRect, clippingParent) { var rect = getClientRectFromMixedType(element, clippingParent); accRect.top = max(rect.top, accRect.top); accRect.right = min(rect.right, accRect.right); accRect.bottom = min(rect.bottom, accRect.bottom); accRect.left = max(rect.left, accRect.left); return accRect; }, getClientRectFromMixedType(element, firstClippingParent)); clippingRect.width = clippingRect.right - clippingRect.left; clippingRect.height = clippingRect.bottom - clippingRect.top; clippingRect.x = clippingRect.left; clippingRect.y = clippingRect.top; return clippingRect; } // node_modules/@popperjs/core/lib/utils/computeOffsets.js function computeOffsets(_ref) { var reference2 = _ref.reference, element = _ref.element, placement = _ref.placement; var basePlacement = placement ? getBasePlacement(placement) : null; var variation = placement ? getVariation(placement) : null; var commonX = reference2.x + reference2.width / 2 - element.width / 2; var commonY = reference2.y + reference2.height / 2 - element.height / 2; var offsets; switch (basePlacement) { case top: offsets = { x: commonX, y: reference2.y - element.height }; break; case bottom: offsets = { x: commonX, y: reference2.y + reference2.height }; break; case right: offsets = { x: reference2.x + reference2.width, y: commonY }; break; case left: offsets = { x: reference2.x - element.width, y: commonY }; break; default: offsets = { x: reference2.x, y: reference2.y }; } var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null; if (mainAxis != null) { var len = mainAxis === "y" ? "height" : "width"; switch (variation) { case start: offsets[mainAxis] = offsets[mainAxis] - (reference2[len] / 2 - element[len] / 2); break; case end: offsets[mainAxis] = offsets[mainAxis] + (reference2[len] / 2 - element[len] / 2); break; default: } } return offsets; } // node_modules/@popperjs/core/lib/utils/detectOverflow.js function detectOverflow(state, options2) { if (options2 === void 0) { options2 = {}; } var _options = options2, _options$placement = _options.placement, placement = _options$placement === void 0 ? state.placement : _options$placement, _options$boundary = _options.boundary, boundary = _options$boundary === void 0 ? clippingParents : _options$boundary, _options$rootBoundary = _options.rootBoundary, rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary, _options$elementConte = _options.elementContext, elementContext = _options$elementConte === void 0 ? popper : _options$elementConte, _options$altBoundary = _options.altBoundary, altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary, _options$padding = _options.padding, padding = _options$padding === void 0 ? 0 : _options$padding; var paddingObject = mergePaddingObject(typeof padding !== "number" ? padding : expandToHashMap(padding, basePlacements)); var altContext = elementContext === popper ? reference : popper; var popperRect = state.rects.popper; var element = state.elements[altBoundary ? altContext : elementContext]; var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary); var referenceClientRect = getBoundingClientRect(state.elements.reference); var popperOffsets2 = computeOffsets({ reference: referenceClientRect, element: popperRect, strategy: "absolute", placement }); var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets2)); var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; var overflowOffsets = { top: clippingClientRect.top - elementClientRect.top + paddingObject.top, bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom, left: clippingClientRect.left - elementClientRect.left + paddingObject.left, right: elementClientRect.right - clippingClientRect.right + paddingObject.right }; var offsetData = state.modifiersData.offset; if (elementContext === popper && offsetData) { var offset2 = offsetData[placement]; Object.keys(overflowOffsets).forEach(function(key) { var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1; var axis = [top, bottom].indexOf(key) >= 0 ? "y" : "x"; overflowOffsets[key] += offset2[axis] * multiply; }); } return overflowOffsets; } // node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js function computeAutoPlacement(state, options2) { if (options2 === void 0) { options2 = {}; } var _options = options2, placement = _options.placement, boundary = _options.boundary, rootBoundary = _options.rootBoundary, padding = _options.padding, flipVariations = _options.flipVariations, _options$allowedAutoP = _options.allowedAutoPlacements, allowedAutoPlacements = _options$allowedAutoP === void 0 ? placements : _options$allowedAutoP; var variation = getVariation(placement); var placements2 = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function(placement2) { return getVariation(placement2) === variation; }) : basePlacements; var allowedPlacements = placements2.filter(function(placement2) { return allowedAutoPlacements.indexOf(placement2) >= 0; }); if (allowedPlacements.length === 0) { allowedPlacements = placements2; if (true) { console.error(["Popper: The `allowedAutoPlacements` option did not allow any", "placements. Ensure the `placement` option matches the variation", "of the allowed placements.", 'For example, "auto" cannot be used to allow "bottom-start".', 'Use "auto-start" instead.'].join(" ")); } } var overflows = allowedPlacements.reduce(function(acc, placement2) { acc[placement2] = detectOverflow(state, { placement: placement2, boundary, rootBoundary, padding })[getBasePlacement(placement2)]; return acc; }, {}); return Object.keys(overflows).sort(function(a, b) { return overflows[a] - overflows[b]; }); } // node_modules/@popperjs/core/lib/modifiers/flip.js function getExpandedFallbackPlacements(placement) { if (getBasePlacement(placement) === auto) { return []; } var oppositePlacement = getOppositePlacement(placement); return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)]; } function flip(_ref) { var state = _ref.state, options2 = _ref.options, name = _ref.name; if (state.modifiersData[name]._skip) { return; } var _options$mainAxis = options2.mainAxis, checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, _options$altAxis = options2.altAxis, checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis, specifiedFallbackPlacements = options2.fallbackPlacements, padding = options2.padding, boundary = options2.boundary, rootBoundary = options2.rootBoundary, altBoundary = options2.altBoundary, _options$flipVariatio = options2.flipVariations, flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio, allowedAutoPlacements = options2.allowedAutoPlacements; var preferredPlacement = state.options.placement; var basePlacement = getBasePlacement(preferredPlacement); var isBasePlacement = basePlacement === preferredPlacement; var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement)); var placements2 = [preferredPlacement].concat(fallbackPlacements).reduce(function(acc, placement2) { return acc.concat(getBasePlacement(placement2) === auto ? computeAutoPlacement(state, { placement: placement2, boundary, rootBoundary, padding, flipVariations, allowedAutoPlacements }) : placement2); }, []); var referenceRect = state.rects.reference; var popperRect = state.rects.popper; var checksMap = /* @__PURE__ */ new Map(); var makeFallbackChecks = true; var firstFittingPlacement = placements2[0]; for (var i = 0; i < placements2.length; i++) { var placement = placements2[i]; var _basePlacement = getBasePlacement(placement); var isStartVariation = getVariation(placement) === start; var isVertical = [top, bottom].indexOf(_basePlacement) >= 0; var len = isVertical ? "width" : "height"; var overflow = detectOverflow(state, { placement, boundary, rootBoundary, altBoundary, padding }); var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top; if (referenceRect[len] > popperRect[len]) { mainVariationSide = getOppositePlacement(mainVariationSide); } var altVariationSide = getOppositePlacement(mainVariationSide); var checks = []; if (checkMainAxis) { checks.push(overflow[_basePlacement] <= 0); } if (checkAltAxis) { checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0); } if (checks.every(function(check) { return check; })) { firstFittingPlacement = placement; makeFallbackChecks = false; break; } checksMap.set(placement, checks); } if (makeFallbackChecks) { var numberOfChecks = flipVariations ? 3 : 1; var _loop = function _loop2(_i2) { var fittingPlacement = placements2.find(function(placement2) { var checks2 = checksMap.get(placement2); if (checks2) { return checks2.slice(0, _i2).every(function(check) { return check; }); } }); if (fittingPlacement) { firstFittingPlacement = fittingPlacement; return "break"; } }; for (var _i = numberOfChecks; _i > 0; _i--) { var _ret = _loop(_i); if (_ret === "break") break; } } if (state.placement !== firstFittingPlacement) { state.modifiersData[name]._skip = true; state.placement = firstFittingPlacement; state.reset = true; } } var flip_default = { name: "flip", enabled: true, phase: "main", fn: flip, requiresIfExists: ["offset"], data: { _skip: false } }; // node_modules/@popperjs/core/lib/modifiers/hide.js function getSideOffsets(overflow, rect, preventedOffsets) { if (preventedOffsets === void 0) { preventedOffsets = { x: 0, y: 0 }; } return { top: overflow.top - rect.height - preventedOffsets.y, right: overflow.right - rect.width + preventedOffsets.x, bottom: overflow.bottom - rect.height + preventedOffsets.y, left: overflow.left - rect.width - preventedOffsets.x }; } function isAnySideFullyClipped(overflow) { return [top, right, bottom, left].some(function(side) { return overflow[side] >= 0; }); } function hide(_ref) { var state = _ref.state, name = _ref.name; var referenceRect = state.rects.reference; var popperRect = state.rects.popper; var preventedOffsets = state.modifiersData.preventOverflow; var referenceOverflow = detectOverflow(state, { elementContext: "reference" }); var popperAltOverflow = detectOverflow(state, { altBoundary: true }); var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect); var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets); var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets); var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets); state.modifiersData[name] = { referenceClippingOffsets, popperEscapeOffsets, isReferenceHidden, hasPopperEscaped }; state.attributes.popper = Object.assign({}, state.attributes.popper, { "data-popper-reference-hidden": isReferenceHidden, "data-popper-escaped": hasPopperEscaped }); } var hide_default = { name: "hide", enabled: true, phase: "main", requiresIfExists: ["preventOverflow"], fn: hide }; // node_modules/@popperjs/core/lib/modifiers/offset.js function distanceAndSkiddingToXY(placement, rects, offset2) { var basePlacement = getBasePlacement(placement); var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1; var _ref = typeof offset2 === "function" ? offset2(Object.assign({}, rects, { placement })) : offset2, skidding = _ref[0], distance = _ref[1]; skidding = skidding || 0; distance = (distance || 0) * invertDistance; return [left, right].indexOf(basePlacement) >= 0 ? { x: distance, y: skidding } : { x: skidding, y: distance }; } function offset(_ref2) { var state = _ref2.state, options2 = _ref2.options, name = _ref2.name; var _options$offset = options2.offset, offset2 = _options$offset === void 0 ? [0, 0] : _options$offset; var data = placements.reduce(function(acc, placement) { acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset2); return acc; }, {}); var _data$state$placement = data[state.placement], x = _data$state$placement.x, y = _data$state$placement.y; if (state.modifiersData.popperOffsets != null) { state.modifiersData.popperOffsets.x += x; state.modifiersData.popperOffsets.y += y; } state.modifiersData[name] = data; } var offset_default = { name: "offset", enabled: true, phase: "main", requires: ["popperOffsets"], fn: offset }; // node_modules/@popperjs/core/lib/modifiers/popperOffsets.js function popperOffsets(_ref) { var state = _ref.state, name = _ref.name; state.modifiersData[name] = computeOffsets({ reference: state.rects.reference, element: state.rects.popper, strategy: "absolute", placement: state.placement }); } var popperOffsets_default = { name: "popperOffsets", enabled: true, phase: "read", fn: popperOffsets, data: {} }; // node_modules/@popperjs/core/lib/utils/getAltAxis.js function getAltAxis(axis) { return axis === "x" ? "y" : "x"; } // node_modules/@popperjs/core/lib/modifiers/preventOverflow.js function preventOverflow(_ref) { var state = _ref.state, options2 = _ref.options, name = _ref.name; var _options$mainAxis = options2.mainAxis, checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, _options$altAxis = options2.altAxis, checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis, boundary = options2.boundary, rootBoundary = options2.rootBoundary, altBoundary = options2.altBoundary, padding = options2.padding, _options$tether = options2.tether, tether = _options$tether === void 0 ? true : _options$tether, _options$tetherOffset = options2.tetherOffset, tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset; var overflow = detectOverflow(state, { boundary, rootBoundary, padding, altBoundary }); var basePlacement = getBasePlacement(state.placement); var variation = getVariation(state.placement); var isBasePlacement = !variation; var mainAxis = getMainAxisFromPlacement(basePlacement); var altAxis = getAltAxis(mainAxis); var popperOffsets2 = state.modifiersData.popperOffsets; var referenceRect = state.rects.reference; var popperRect = state.rects.popper; var tetherOffsetValue = typeof tetherOffset === "function" ? tetherOffset(Object.assign({}, state.rects, { placement: state.placement })) : tetherOffset; var normalizedTetherOffsetValue = typeof tetherOffsetValue === "number" ? { mainAxis: tetherOffsetValue, altAxis: tetherOffsetValue } : Object.assign({ mainAxis: 0, altAxis: 0 }, tetherOffsetValue); var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null; var data = { x: 0, y: 0 }; if (!popperOffsets2) { return; } if (checkMainAxis) { var _offsetModifierState$; var mainSide = mainAxis === "y" ? top : left; var altSide = mainAxis === "y" ? bottom : right; var len = mainAxis === "y" ? "height" : "width"; var offset2 = popperOffsets2[mainAxis]; var min2 = offset2 + overflow[mainSide]; var max2 = offset2 - overflow[altSide]; var additive = tether ? -popperRect[len] / 2 : 0; var minLen = variation === start ? referenceRect[len] : popperRect[len]; var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; var arrowElement = state.elements.arrow; var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : { width: 0, height: 0 }; var arrowPaddingObject = state.modifiersData["arrow#persistent"] ? state.modifiersData["arrow#persistent"].padding : getFreshSideObject(); var arrowPaddingMin = arrowPaddingObject[mainSide]; var arrowPaddingMax = arrowPaddingObject[altSide]; var arrowLen = within(0, referenceRect[len], arrowRect[len]); var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis; var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis; var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow); var clientOffset = arrowOffsetParent ? mainAxis === "y" ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0; var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0; var tetherMin = offset2 + minOffset - offsetModifierValue - clientOffset; var tetherMax = offset2 + maxOffset - offsetModifierValue; var preventedOffset = within(tether ? min(min2, tetherMin) : min2, offset2, tether ? max(max2, tetherMax) : max2); popperOffsets2[mainAxis] = preventedOffset; data[mainAxis] = preventedOffset - offset2; } if (checkAltAxis) { var _offsetModifierState$2; var _mainSide = mainAxis === "x" ? top : left; var _altSide = mainAxis === "x" ? bottom : right; var _offset = popperOffsets2[altAxis]; var _len = altAxis === "y" ? "height" : "width"; var _min = _offset + overflow[_mainSide]; var _max = _offset - overflow[_altSide]; var isOriginSide = [top, left].indexOf(basePlacement) !== -1; var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0; var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis; var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max; var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max); popperOffsets2[altAxis] = _preventedOffset; data[altAxis] = _preventedOffset - _offset; } state.modifiersData[name] = data; } var preventOverflow_default = { name: "preventOverflow", enabled: true, phase: "main", fn: preventOverflow, requiresIfExists: ["offset"] }; // node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js function getHTMLElementScroll(element) { return { scrollLeft: element.scrollLeft, scrollTop: element.scrollTop }; } // node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js function getNodeScroll(node) { if (node === getWindow(node) || !isHTMLElement(node)) { return getWindowScroll(node); } else { return getHTMLElementScroll(node); } } // node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js function isElementScaled(element) { var rect = element.getBoundingClientRect(); var scaleX = round(rect.width) / element.offsetWidth || 1; var scaleY = round(rect.height) / element.offsetHeight || 1; return scaleX !== 1 || scaleY !== 1; } function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) { if (isFixed === void 0) { isFixed = false; } var isOffsetParentAnElement = isHTMLElement(offsetParent); var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent); var documentElement = getDocumentElement(offsetParent); var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled); var scroll = { scrollLeft: 0, scrollTop: 0 }; var offsets = { x: 0, y: 0 }; if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) { if (getNodeName(offsetParent) !== "body" || // https://github.com/popperjs/popper-core/issues/1078 isScrollParent(documentElement)) { scroll = getNodeScroll(offsetParent); } if (isHTMLElement(offsetParent)) { offsets = getBoundingClientRect(offsetParent, true); offsets.x += offsetParent.clientLeft; offsets.y += offsetParent.clientTop; } else if (documentElement) { offsets.x = getWindowScrollBarX(documentElement); } } return { x: rect.left + scroll.scrollLeft - offsets.x, y: rect.top + scroll.scrollTop - offsets.y, width: rect.width, height: rect.height }; } // node_modules/@popperjs/core/lib/utils/orderModifiers.js function order(modifiers) { var map2 = /* @__PURE__ */ new Map(); var visited = /* @__PURE__ */ new Set(); var result = []; modifiers.forEach(function(modifier) { map2.set(modifier.name, modifier); }); function sort(modifier) { visited.add(modifier.name); var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []); requires.forEach(function(dep) { if (!visited.has(dep)) { var depModifier = map2.get(dep); if (depModifier) { sort(depModifier); } } }); result.push(modifier); } modifiers.forEach(function(modifier) { if (!visited.has(modifier.name)) { sort(modifier); } }); return result; } function orderModifiers(modifiers) { var orderedModifiers = order(modifiers); return modifierPhases.reduce(function(acc, phase) { return acc.concat(orderedModifiers.filter(function(modifier) { return modifier.phase === phase; })); }, []); } // node_modules/@popperjs/core/lib/utils/debounce.js function debounce(fn2) { var pending; return function() { if (!pending) { pending = new Promise(function(resolve) { Promise.resolve().then(function() { pending = void 0; resolve(fn2()); }); }); } return pending; }; } // node_modules/@popperjs/core/lib/utils/format.js function format(str) { for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } return [].concat(args).reduce(function(p, c) { return p.replace(/%s/, c); }, str); } // node_modules/@popperjs/core/lib/utils/validateModifiers.js var INVALID_MODIFIER_ERROR = 'Popper: modifier "%s" provided an invalid %s property, expected %s but got %s'; var MISSING_DEPENDENCY_ERROR = 'Popper: modifier "%s" requires "%s", but "%s" modifier is not available'; var VALID_PROPERTIES = ["name", "enabled", "phase", "fn", "effect", "requires", "options"]; function validateModifiers(modifiers) { modifiers.forEach(function(modifier) { [].concat(Object.keys(modifier), VALID_PROPERTIES).filter(function(value, index, self) { return self.indexOf(value) === index; }).forEach(function(key) { switch (key) { case "name": if (typeof modifier.name !== "string") { console.error(format(INVALID_MODIFIER_ERROR, String(modifier.name), '"name"', '"string"', '"' + String(modifier.name) + '"')); } break; case "enabled": if (typeof modifier.enabled !== "boolean") { console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"enabled"', '"boolean"', '"' + String(modifier.enabled) + '"')); } break; case "phase": if (modifierPhases.indexOf(modifier.phase) < 0) { console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"phase"', "either " + modifierPhases.join(", "), '"' + String(modifier.phase) + '"')); } break; case "fn": if (typeof modifier.fn !== "function") { console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"fn"', '"function"', '"' + String(modifier.fn) + '"')); } break; case "effect": if (modifier.effect != null && typeof modifier.effect !== "function") { console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"effect"', '"function"', '"' + String(modifier.fn) + '"')); } break; case "requires": if (modifier.requires != null && !Array.isArray(modifier.requires)) { console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"requires"', '"array"', '"' + String(modifier.requires) + '"')); } break; case "requiresIfExists": if (!Array.isArray(modifier.requiresIfExists)) { console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"requiresIfExists"', '"array"', '"' + String(modifier.requiresIfExists) + '"')); } break; case "options": case "data": break; default: console.error('PopperJS: an invalid property has been provided to the "' + modifier.name + '" modifier, valid properties are ' + VALID_PROPERTIES.map(function(s) { return '"' + s + '"'; }).join(", ") + '; but "' + key + '" was provided.'); } modifier.requires && modifier.requires.forEach(function(requirement) { if (modifiers.find(function(mod) { return mod.name === requirement; }) == null) { console.error(format(MISSING_DEPENDENCY_ERROR, String(modifier.name), requirement, requirement)); } }); }); }); } // node_modules/@popperjs/core/lib/utils/uniqueBy.js function uniqueBy(arr, fn2) { var identifiers = /* @__PURE__ */ new Set(); return arr.filter(function(item) { var identifier = fn2(item); if (!identifiers.has(identifier)) { identifiers.add(identifier); return true; } }); } // node_modules/@popperjs/core/lib/utils/mergeByName.js function mergeByName(modifiers) { var merged = modifiers.reduce(function(merged2, current) { var existing = merged2[current.name]; merged2[current.name] = existing ? Object.assign({}, existing, current, { options: Object.assign({}, existing.options, current.options), data: Object.assign({}, existing.data, current.data) }) : current; return merged2; }, {}); return Object.keys(merged).map(function(key) { return merged[key]; }); } // node_modules/@popperjs/core/lib/createPopper.js var INVALID_ELEMENT_ERROR = "Popper: Invalid reference or popper argument provided. They must be either a DOM element or virtual element."; var INFINITE_LOOP_ERROR = "Popper: An infinite loop in the modifiers cycle has been detected! The cycle has been interrupted to prevent a browser crash."; var DEFAULT_OPTIONS = { placement: "bottom", modifiers: [], strategy: "absolute" }; function areValidElements() { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return !args.some(function(element) { return !(element && typeof element.getBoundingClientRect === "function"); }); } function popperGenerator(generatorOptions) { if (generatorOptions === void 0) { generatorOptions = {}; } var _generatorOptions = generatorOptions, _generatorOptions$def = _generatorOptions.defaultModifiers, defaultModifiers2 = _generatorOptions$def === void 0 ? [] : _generatorOptions$def, _generatorOptions$def2 = _generatorOptions.defaultOptions, defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2; return function createPopper2(reference2, popper2, options2) { if (options2 === void 0) { options2 = defaultOptions; } var state = { placement: "bottom", orderedModifiers: [], options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions), modifiersData: {}, elements: { reference: reference2, popper: popper2 }, attributes: {}, styles: {} }; var effectCleanupFns = []; var isDestroyed = false; var instance = { state, setOptions: function setOptions(setOptionsAction) { var options3 = typeof setOptionsAction === "function" ? setOptionsAction(state.options) : setOptionsAction; cleanupModifierEffects(); state.options = Object.assign({}, defaultOptions, state.options, options3); state.scrollParents = { reference: isElement(reference2) ? listScrollParents(reference2) : reference2.contextElement ? listScrollParents(reference2.contextElement) : [], popper: listScrollParents(popper2) }; var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers2, state.options.modifiers))); state.orderedModifiers = orderedModifiers.filter(function(m) { return m.enabled; }); if (true) { var modifiers = uniqueBy([].concat(orderedModifiers, state.options.modifiers), function(_ref) { var name = _ref.name; return name; }); validateModifiers(modifiers); if (getBasePlacement(state.options.placement) === auto) { var flipModifier = state.orderedModifiers.find(function(_ref2) { var name = _ref2.name; return name === "flip"; }); if (!flipModifier) { console.error(['Popper: "auto" placements require the "flip" modifier be', "present and enabled to work."].join(" ")); } } var _getComputedStyle = getComputedStyle2(popper2), marginTop = _getComputedStyle.marginTop, marginRight = _getComputedStyle.marginRight, marginBottom = _getComputedStyle.marginBottom, marginLeft = _getComputedStyle.marginLeft; if ([marginTop, marginRight, marginBottom, marginLeft].some(function(margin) { return parseFloat(margin); })) { console.warn(['Popper: CSS "margin" styles cannot be used to apply padding', "between the popper and its reference element or boundary.", "To replicate margin, use the `offset` modifier, as well as", "the `padding` option in the `preventOverflow` and `flip`", "modifiers."].join(" ")); } } runModifierEffects(); return instance.update(); }, // Sync update – it will always be executed, even if not necessary. This // is useful for low frequency updates where sync behavior simplifies the // logic. // For high frequency updates (e.g. `resize` and `scroll` events), always // prefer the async Popper#update method forceUpdate: function forceUpdate() { if (isDestroyed) { return; } var _state$elements = state.elements, reference3 = _state$elements.reference, popper3 = _state$elements.popper; if (!areValidElements(reference3, popper3)) { if (true) { console.error(INVALID_ELEMENT_ERROR); } return; } state.rects = { reference: getCompositeRect(reference3, getOffsetParent(popper3), state.options.strategy === "fixed"), popper: getLayoutRect(popper3) }; state.reset = false; state.placement = state.options.placement; state.orderedModifiers.forEach(function(modifier) { return state.modifiersData[modifier.name] = Object.assign({}, modifier.data); }); var __debug_loops__ = 0; for (var index = 0; index < state.orderedModifiers.length; index++) { if (true) { __debug_loops__ += 1; if (__debug_loops__ > 100) { console.error(INFINITE_LOOP_ERROR); break; } } if (state.reset === true) { state.reset = false; index = -1; continue; } var _state$orderedModifie = state.orderedModifiers[index], fn2 = _state$orderedModifie.fn, _state$orderedModifie2 = _state$orderedModifie.options, _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2, name = _state$orderedModifie.name; if (typeof fn2 === "function") { state = fn2({ state, options: _options, name, instance }) || state; } } }, // Async and optimistically optimized update – it will not be executed if // not necessary (debounced to run at most once-per-tick) update: debounce(function() { return new Promise(function(resolve) { instance.forceUpdate(); resolve(state); }); }), destroy: function destroy() { cleanupModifierEffects(); isDestroyed = true; } }; if (!areValidElements(reference2, popper2)) { if (true) { console.error(INVALID_ELEMENT_ERROR); } return instance; } instance.setOptions(options2).then(function(state2) { if (!isDestroyed && options2.onFirstUpdate) { options2.onFirstUpdate(state2); } }); function runModifierEffects() { state.orderedModifiers.forEach(function(_ref3) { var name = _ref3.name, _ref3$options = _ref3.options, options3 = _ref3$options === void 0 ? {} : _ref3$options, effect4 = _ref3.effect; if (typeof effect4 === "function") { var cleanupFn = effect4({ state, name, instance, options: options3 }); var noopFn = function noopFn2() { }; effectCleanupFns.push(cleanupFn || noopFn); } }); } function cleanupModifierEffects() { effectCleanupFns.forEach(function(fn2) { return fn2(); }); effectCleanupFns = []; } return instance; }; } // node_modules/@popperjs/core/lib/popper.js var defaultModifiers = [eventListeners_default, popperOffsets_default, computeStyles_default, applyStyles_default, offset_default, flip_default, preventOverflow_default, arrow_default, hide_default]; var createPopper = /* @__PURE__ */ popperGenerator({ defaultModifiers }); // src/suggester/suggest.ts var wrapAround = (value, size) => { return (value % size + size) % size; }; var Suggest = class { constructor(owner, containerEl, scope) { this.owner = owner; this.containerEl = containerEl; containerEl.on( "click", ".suggestion-item", this.onSuggestionClick.bind(this) ); containerEl.on( "mousemove", ".suggestion-item", this.onSuggestionMouseover.bind(this) ); scope.register([], "ArrowUp", (event) => { if (!event.isComposing) { this.setSelectedItem(this.selectedItem - 1, true); return false; } }); scope.register([], "ArrowDown", (event) => { if (!event.isComposing) { this.setSelectedItem(this.selectedItem + 1, true); return false; } }); scope.register([], "Enter", (event) => { if (!event.isComposing) { this.useSelectedItem(event); return false; } }); } onSuggestionClick(event, el) { event.preventDefault(); const item = this.suggestions.indexOf(el); this.setSelectedItem(item, false); this.useSelectedItem(event); } onSuggestionMouseover(_event, el) { const item = this.suggestions.indexOf(el); this.setSelectedItem(item, false); } setSuggestions(values) { this.containerEl.empty(); const suggestionEls = []; values.forEach((value) => { const suggestionEl = this.containerEl.createDiv("suggestion-item"); this.owner.renderSuggestion(value, suggestionEl); suggestionEls.push(suggestionEl); }); this.values = values; this.suggestions = suggestionEls; this.setSelectedItem(0, false); } useSelectedItem(event) { const currentValue = this.values[this.selectedItem]; if (currentValue) { this.owner.selectSuggestion(currentValue, event); } } setSelectedItem(selectedIndex, scrollIntoView) { const normalizedIndex = wrapAround( selectedIndex, this.suggestions.length ); const prevSelectedSuggestion = this.suggestions[this.selectedItem]; const selectedSuggestion = this.suggestions[normalizedIndex]; prevSelectedSuggestion == null ? void 0 : prevSelectedSuggestion.removeClass("is-selected"); selectedSuggestion == null ? void 0 : selectedSuggestion.addClass("is-selected"); this.selectedItem = normalizedIndex; if (scrollIntoView) { selectedSuggestion.scrollIntoView(false); } } }; var TextInputSuggest = class { constructor(inputEl) { this.inputEl = inputEl; this.scope = new import_obsidian6.Scope(); this.suggestEl = createDiv("suggestion-container"); const suggestion = this.suggestEl.createDiv("suggestion"); this.suggest = new Suggest(this, suggestion, this.scope); this.scope.register([], "Escape", this.close.bind(this)); this.inputEl.addEventListener("input", this.onInputChanged.bind(this)); this.inputEl.addEventListener("focus", this.onInputChanged.bind(this)); this.inputEl.addEventListener("blur", this.close.bind(this)); this.suggestEl.on( "mousedown", ".suggestion-container", (event) => { event.preventDefault(); } ); } onInputChanged() { const inputStr = this.inputEl.value; const suggestions = this.getSuggestions(inputStr); if (!suggestions) { this.close(); return; } if (suggestions.length > 0) { this.suggest.setSuggestions(suggestions); this.open(app.dom.appContainerEl, this.inputEl); } else { this.close(); } } open(container, inputEl) { app.keymap.pushScope(this.scope); container.appendChild(this.suggestEl); this.popper = createPopper(inputEl, this.suggestEl, { placement: "bottom-start", modifiers: [ { name: "sameWidth", enabled: true, fn: ({ state, instance }) => { const targetWidth = `${state.rects.reference.width}px`; if (state.styles.popper.width === targetWidth) { return; } state.styles.popper.width = targetWidth; instance.update(); }, phase: "beforeWrite", requires: ["computeStyles"] } ] }); } close() { app.keymap.popScope(this.scope); this.suggest.setSuggestions([]); if (this.popper) this.popper.destroy(); this.suggestEl.detach(); } }; // src/suggester/FileSuggester.ts var FileSuggest = class extends TextInputSuggest { constructor(inputEl, plugin, folder, extenstion = "md") { super(inputEl); this.inputEl = inputEl; this.plugin = plugin; this.folder = folder; this.extenstion = extenstion; this.plugin = plugin; } getSuggestions(input_str) { const all_files = []; try { all_files.push(...get_tfiles_from_folder(this.plugin, this.folder)); } catch (error) { } const files = []; const lower_input_str = input_str.toLowerCase(); all_files.forEach((file) => { if (file instanceof import_obsidian7.TFile && file.extension === this.extenstion && file.path.toLowerCase().contains(lower_input_str)) { files.push(file); } }); return files; } renderSuggestion(file, el) { el.setText(file.path); } selectSuggestion(file) { this.inputEl.value = file.path; this.inputEl.trigger("input"); this.close(); } }; // src/fields/models/abstractModels/AbstractList.ts var SourceType = /* @__PURE__ */ ((SourceType2) => { SourceType2["ValuesList"] = "ValuesList"; SourceType2["ValuesListNotePath"] = "ValuesListNotePath"; SourceType2["ValuesFromDVQuery"] = "ValuesFromDVQuery"; return SourceType2; })(SourceType || {}); var SourceTypeDisplay = { "ValuesList": "Values defined in these settings", "ValuesListNotePath": "Values from a note", "ValuesFromDVQuery": "Values returned from a dataview query" }; var DefaultOptions3 = { sourceType: "ValuesList", valuesList: {} }; function settingsModal3(Base25) { return class SettingsModal extends Base25 { constructor() { super(...arguments); this.valuesPromptComponents = []; } createSettingContainer() { const container = this.optionsContainer; const sourceTypeContainer = container.createDiv({ cls: "field-container" }); sourceTypeContainer.createDiv({ text: "Values source type", cls: "label" }); sourceTypeContainer.createDiv({ cls: "spacer" }); this.sourceTypeSelector = new import_obsidian8.DropdownComponent(sourceTypeContainer); Object.keys(SourceType).forEach((option) => this.sourceTypeSelector.addOption(option, SourceTypeDisplay[option])); this.sourceTypeSelector.setValue(this.field.options.sourceType); const valuesListNotePathContainer = this.createListNotePathContainer(container); const presetValuesFieldsContainer = this.createValuesListContainer(container); const valuesFromDVQueryContainer = this.createValuesFromDVQueryContainer(container); const valuesContainers = { "ValuesList": presetValuesFieldsContainer, "ValuesListNotePath": valuesListNotePathContainer, "ValuesFromDVQuery": valuesFromDVQueryContainer }; this.sourceTypeSelector.onChange((value) => { this.field.options.sourceType = value; this.displaySelectedTypeContainer(valuesContainers, value); }); this.displaySelectedTypeContainer(valuesContainers, this.field.options.sourceType); } validateOptions() { let error = false; let prevComponent; const vPC = this.valuesPromptComponents; vPC.forEach((input, i) => { var _a, _b; if (vPC.length > 1) { if (i === 0) { prevComponent = vPC[vPC.length - 1]; } if (prevComponent.inputEl.value === input.inputEl.value) { setValidationError( input, "Two adjacent values can't be equal" ); error = true; } prevComponent = input; } if (/[,]/gu.test(input.inputEl.value) && ((_a = input.inputEl.parentElement) == null ? void 0 : _a.lastElementChild)) { setValidationError( input, "Values cannot contain a comma" ); error = true; } ; if (input.inputEl.value == "" && ((_b = input.inputEl.parentElement) == null ? void 0 : _b.lastElementChild)) { setValidationError( input, "Values can't be null." ); error = true; } ; }); return !error; } createListNotePathContainer(container) { const valuesListNotePathContainer = container.createDiv({ cls: "field-container" }); valuesListNotePathContainer.createDiv({ text: `Path of the note`, cls: "label" }); this.notePathInput = new import_obsidian8.TextComponent(valuesListNotePathContainer); const input = this.notePathInput; input.inputEl.addClass("full-width"); input.inputEl.addClass("with-label"); new FileSuggest( input.inputEl, this.plugin, "/" ); const listNotePath = this.field.options.valuesListNotePath; input.setValue(listNotePath || ""); input.setPlaceholder("Path/of/the/note.md"); input.onChange((value) => this.field.options.valuesListNotePath = value); return valuesListNotePathContainer; } createValuesListContainer(parentContainer) { const presetValuesFields = parentContainer.createDiv(); const valuesList = presetValuesFields.createDiv(); const valuesListBody = valuesList.createDiv(); Object.keys(this.field.options.valuesList).forEach((key) => { this.valuesPromptComponents.push(this.createValueContainer(valuesListBody, key)); }); this.createAddButton(valuesList, valuesListBody); return presetValuesFields; } createValueContainer(parentNode, key) { const values = this.field.options.valuesList; const presetValue = values[key]; const valueContainer = parentNode.createDiv({ cls: "field-container" }); const input = new import_obsidian8.TextComponent(valueContainer); input.inputEl.addClass("full-width"); input.setValue(presetValue); input.onChange((value) => { this.field.options.valuesList[key] = value; removeValidationError(input); }); const valueRemoveButton = new import_obsidian8.ButtonComponent(valueContainer); valueRemoveButton.setIcon("trash").onClick((evt) => { evt.preventDefault(); removeValidationError(input); this.removePresetValue(key); parentNode.removeChild(valueContainer); this.valuesPromptComponents.remove(input); }); if (key != Object.keys(this.field.options)[0]) { const valueUpgradeButton = new import_obsidian8.ButtonComponent(valueContainer); (0, import_obsidian8.setIcon)(valueUpgradeButton.buttonEl, "up-chevron-glyph"); valueUpgradeButton.onClick((evt) => { const thisValue = values[key]; const inputIndex = this.valuesPromptComponents.indexOf(input); const upperComponent = inputIndex !== -1 ? this.valuesPromptComponents[inputIndex - 1] : this.valuesPromptComponents.last(); if (upperComponent) { const upperValue = upperComponent.inputEl.value; const upperKey = Object.keys(values).filter((k) => values[k] == upperValue)[0]; if (upperKey) { upperComponent.setValue(thisValue); values[upperKey] = thisValue; input.setValue(upperValue); values[key] = upperValue; } ; } ; }); } ; return input; } createValuesFromDVQueryContainer(parentContainer) { const valuesFromDVQueryTopContainer = parentContainer.createDiv({ cls: "vstacked" }); valuesFromDVQueryTopContainer.createEl("span", { text: "Dataview function" }); valuesFromDVQueryTopContainer.createEl("span", { text: "Dataview query returning a list of string ( object is available)", cls: "sub-text" }); const valuesFromDVQueryContainer = valuesFromDVQueryTopContainer.createDiv({ cls: "field-container" }); this.dvQueryInput = new import_obsidian8.TextAreaComponent(valuesFromDVQueryContainer); this.dvQueryInput.inputEl.addClass("full-width"); this.dvQueryInput.inputEl.cols = 65; this.dvQueryInput.inputEl.rows = 8; this.dvQueryInput.setPlaceholder("ex: dv.pages('#student').map(p => p.name)"); this.dvQueryInput.setValue(this.field.options.valuesFromDVQuery || ""); this.dvQueryInput.onChange((value) => { this.field.options.valuesFromDVQuery = value; }); return valuesFromDVQueryTopContainer; } displaySelectedTypeContainer(optionContainers, value) { Object.keys(optionContainers).forEach((key) => { if (key === value) { optionContainers[key].show(); } else { optionContainers[key].hide(); } }); } createAddButton(valuesList, valuesListBody) { const valuesListFooter = valuesList.createDiv(); this.addValue = valuesListFooter.createEl("button"); this.addValue.type = "button"; this.addValue.textContent = "Add a value"; this.addValue.onClickEvent(async (evt) => { evt.preventDefault(); let newKeyNumber = 1; Object.keys(this.field.options.valuesList).forEach((key) => { if (parseInt(key) && parseInt(key) >= newKeyNumber) { newKeyNumber = parseInt(key) + 1; } ; }); const newKey = newKeyNumber.toString(); this.field.options.valuesList[newKey] = ""; this.valuesPromptComponents.push(this.createValueContainer(valuesListBody, newKey)); }); valuesList.createEl("hr"); } removePresetValue(key) { let newValues = {}; for (let _key in this.field.options.valuesList) { if (key !== _key) { newValues[_key] = this.field.options.valuesList[_key]; } ; } ; this.field.options.valuesList = newValues; } }; } function valueModal3(managedField, plugin) { const base = basicSuggestModal(managedField, plugin); return class ValueModal extends base { constructor(...rest) { super(plugin.app); this.managedField = managedField; this.containerEl.addClass("metadata-menu"); const inputContainer = this.containerEl.createDiv({ cls: "suggester-input" }); inputContainer.appendChild(this.inputEl); this.containerEl.find(".prompt").prepend(inputContainer); cleanActions(this.containerEl, ".footer-actions"); const footerActionsContainer = this.containerEl.createDiv({ cls: "footer-actions" }); this.buildAddButton(inputContainer); this.buildFooterActions(footerActionsContainer); } getSuggestions(query) { const values = getOptionsList(this.managedField).filter((o) => o.toLowerCase().includes(query.toLowerCase())); if (this.addButton) { values.some((p) => p === query) || this.managedField.options.sourceType === "ValuesFromDVQuery" || !query ? this.addButton.buttonEl.hide() : this.addButton.buttonEl.show(); } ; return values; } renderSuggestion(value, el) { el.setText(value); el.addClass("value-container"); } onChooseSuggestion(item, evt) { this.saved = true; managedField.save(item); } async onAdd() { throw Error("This class has to implement an onAdd method"); } async addNewValueToSettings() { const newValue = this.inputEl.value; const options2 = this.managedField.options; switch (options2.sourceType) { case "ValuesList": let newOptions; options2.valuesList; newOptions = options2.valuesList || {}; if (Array.isArray(newOptions)) { const newValues = [...newOptions, newValue]; const newObj = {}; for (const [k, v] of newValues) { newObj[`${k}`] = v; } } else if (typeof newOptions === "object") { newOptions[`${Object.keys(newOptions).length + 1}`] = newValue; } this.managedField.options.valuesList = newOptions; break; case "ValuesListNotePath": const path = options2.valuesListNotePath; if (!path) return; const valuesFile = plugin.app.vault.getAbstractFileByPath(path); if (valuesFile instanceof import_obsidian8.TFile && valuesFile.extension == "md") { const result = await plugin.app.vault.read(valuesFile); await plugin.app.vault.modify(valuesFile, `${result} ${newValue}`); await plugin.fieldIndex.getValuesListNotePathValues(); } default: break; } } buildAddButton(container) { this.addButton = new import_obsidian8.ButtonComponent(container); this.addButton.setIcon("plus"); this.addButton.onClick(async () => await this.onAdd()); this.addButton.setCta(); this.addButton.setTooltip("Add this value to this field settings"); this.addButton.buttonEl.hide(); } buildFooterActions(footerActionsContainer) { footerActionsContainer.createDiv({ cls: "spacer" }); this.buildConfirm(footerActionsContainer); const cancelButton = new import_obsidian8.ButtonComponent(footerActionsContainer); cancelButton.setIcon("cross"); cancelButton.onClick(() => this.close()); cancelButton.setTooltip("Cancel"); const clearButton = new import_obsidian8.ButtonComponent(footerActionsContainer); clearButton.setIcon("eraser"); clearButton.setTooltip("Clear field's value(s)"); clearButton.onClick(async () => { await this.clearValues(); this.close(); }); clearButton.buttonEl.addClass("danger"); this.modalEl.appendChild(footerActionsContainer); } buildConfirm(footerActionsContainer) { } async clearValues() { this.managedField.save(""); } }; } function valueString3(managedField) { return `${managedField.value.join(", ")}`; } function displayValue3(managedField, container, onClicked) { if (Array.isArray(managedField.value)) { container.createDiv({ text: valueString3(managedField) }); } else { return baseDisplayValue(managedField, container, onClicked); } } function actions3(plugin, field2, file, location, indexedPath) { const iconName = getIcon(field2.type); const action = async () => { var _a; const eF = await getExistingFieldForIndexedPath2(plugin, file, indexedPath); (_a = fieldValueManager(plugin, field2.id, field2.fileClassName, file, eF, indexedPath)) == null ? void 0 : _a.openModal(); }; if (isSuggest(location)) { location.options.push({ id: `update_${field2.name}`, actionLabel: `Update ${field2.name}`, action, icon: iconName }); } else if (isFieldActions(location)) { location.addOption(`field_${field2.id}_update`, iconName, action, `Update ${field2.name}'s value`); } } function getOptionsStr3(field2) { return field2.options.template || ""; } function getOptionsList(managedField) { var _a; const options2 = managedField.options; let values = []; if (Array.isArray(options2)) { values = options2; } else if (!options2.sourceType) { values = Object.values(options2); } else { switch (options2.sourceType) { case "ValuesList": values = Object.values(options2.valuesList || {}); break; case "ValuesListNotePath": const path = managedField.options.valuesListNotePath; const index = managedField.plugin.fieldIndex; values = path ? index.valuesListNotePathValues.get(path) || [] : []; break; case "ValuesFromDVQuery": { const dvApi = (_a = managedField.plugin.app.plugins.plugins.dataview) == null ? void 0 : _a.api; if (dvApi) { const dvFile = isSingleTargeted(managedField) ? dvApi.page(managedField.target.path) : {}; values = new Function("dv", "current", `return ${managedField.options.valuesFromDVQuery}`)(dvApi, dvFile || {}); } else { values = []; } } break; default: values = []; break; } } return values; } async function enterFieldSetting3(settingModal, field2, speed = 100) { const runner = settingModal.plugin.testRunner; runner.selectInDropDownComponent(settingModal.sourceTypeSelector, field2.options.sourceType); switch (field2.options.sourceType) { case "ValuesList": for (const [key, value] of Object.entries(field2.options.valuesList || {})) { settingModal.addValue.click(); const valueInput = settingModal.valuesPromptComponents[parseInt(key) - 1]; runner.insertInTextComponent(valueInput, value); } break; case "ValuesListNotePath": if (!field2.options.valuesListNotePath) return runner.log("ERROR", `Can't find <${field2.name}> values list note path`); runner.insertInTextComponent(settingModal.notePathInput, field2.options.valuesListNotePath); break; case "ValuesFromDVQuery": if (!field2.options.valuesFromDVQuery) return runner.log("ERROR", `Can't find <${field2.name}> dataview query`); runner.insertInTextComponent(settingModal.dvQueryInput, field2.options.valuesFromDVQuery); break; } } // src/fields/models/Select.ts var import_obsidian9 = require("obsidian"); var Base3 = class { constructor() { this.type = "Select"; this.tagName = "select"; this.icon = "right-triangle"; this.tooltip = "Accepts a single value from a list"; this.colorClass = "select"; } }; var DefaultOptions4 = DefaultOptions3; function settingsModal4(Base25) { return settingsModal3(Base25); } function valueModal4(managedField, plugin) { const base = valueModal3(managedField, plugin); return class ValueModal extends base { async onAdd() { await this.addNewValueToSettings(); managedField.save(this.inputEl.value); this.close(); } renderSuggestion(value, el) { el.setText(value); el.addClass("value-container"); if (value === managedField.value) el.addClass("value-checked"); } onChooseSuggestion(item, evt) { this.saved = true; managedField.save(item); } }; } function valueString4(managedField) { return valueString3(managedField); } function displayValue4(managedField, container, onClicked) { return displayValue3(managedField, container, onClicked); } function createDvField3(managedField, dv, p, fieldContainer, attrs = {}) { var _a; attrs.cls = "value-container"; fieldContainer.appendChild(dv.el("span", managedField.value || "", attrs)); const spacer = fieldContainer.createEl("div", { cls: "spacer-1" }); const dropDownButton = fieldContainer.createEl("button"); (0, import_obsidian9.setIcon)(dropDownButton, "down-chevron-glyph"); const file = managedField.plugin.app.vault.getAbstractFileByPath(p["file"]["path"]); if (file instanceof import_obsidian9.TFile && file.extension == "md") { dropDownButton.onclick = async () => managedField.openModal(); } else { dropDownButton.onclick = () => { }; } if (!((_a = attrs == null ? void 0 : attrs.options) == null ? void 0 : _a.alwaysOn)) { dropDownButton.hide(); spacer.show(); fieldContainer.onmouseover = () => { dropDownButton.show(); spacer.hide(); }; fieldContainer.onmouseout = () => { dropDownButton.hide(); spacer.show(); }; } } function actions4(plugin, field2, file, location, indexedPath) { return actions3(plugin, field2, file, location, indexedPath); } function getOptionsStr4(field2) { return getOptionsStr3(field2); } function validateValue3(managedField) { return getOptionsList(managedField).includes(managedField.value); } async function enterFieldSetting4(settingModal, field2, speed = 100) { return enterFieldSetting3(settingModal, field2, speed); } // src/fields/models/Multi.ts var import_obsidian11 = require("obsidian"); // src/fields/models/abstractModels/AbstractFile.ts var import_obsidian10 = require("obsidian"); // src/utils/linksUtils.ts var getLinksOrTextString = (value, file) => { const links = typeof value === "string" ? extractLinks(value) : void 0; let result = []; if (links) { links.forEach((_link, i) => { const link = getLink(_link, file); if (link == null ? void 0 : link.path) { const linkText = link.path.split("/").last() || ""; result.push(linkText.replace(/(.*).md/, "$1")); } if (i < links.length - 1) { result.push(" | "); } }); } else { const values = Array.isArray(value) ? value : [value]; values.forEach((value2, i) => { if (value2) { const link = getLink(value2, file); if (link == null ? void 0 : link.path) { const linkText = link.path.split("/").last() || ""; result.push(linkText.replace(/(.*).md/, "$1")); } else { result.push(value2); } if (i < values.length - 1) { result.push(" | "); } } }); } return result.join(""); }; var displayLinksOrText = (value, file, container, plugin, onClicked) => { const links = typeof value === "string" ? extractLinks(value) : void 0; if (links) { links.forEach((_link, i) => { const link = getLink(_link, file); if (link == null ? void 0 : link.path) { const linkText = link.path.split("/").last() || ""; const linkEl = container.createEl("a", { text: linkText.replace(/(.*).md/, "$1") }); linkEl.onclick = () => { plugin.app.workspace.openLinkText(link.path, file.path, true); onClicked(); }; } if (i < links.length - 1) { container.createEl("span", { text: " | " }); } }); } else { const values = Array.isArray(value) ? value : [value]; values.forEach((value2, i) => { if (value2) { const link = getLink(value2, file); if (link == null ? void 0 : link.path) { const linkText = link.path.split("/").last() || ""; const linkEl = container.createEl("a", { text: linkText.replace(/(.*).md/, "$1") }); linkEl.onclick = () => { plugin.app.workspace.openLinkText(link.path, file.path, true); onClicked(); }; } else { container.createEl("span", { text: value2 }); } if (i < values.length - 1) { container.createEl("span", { text: " | " }); } } }); } }; // src/fields/models/abstractModels/AbstractFile.ts var Base4 = class { constructor() { this.tagName = "file"; this.icon = "link"; this.colorClass = "file"; } }; var DefaultOptions5 = {}; function settingsModal5(Base25) { return class SettingModal extends Base25 { constructor() { super(...arguments); this.createSettingContainer = () => { this.createQueryContainer(this.optionsContainer); this.createCustomRenderingContainer(this.optionsContainer); this.createCustomSortingContainer(this.optionsContainer); }; } validateOptions() { return true; } createQueryContainer(container) { const dvQueryStringTopContainer = container.createDiv({ cls: "vstacked" }); dvQueryStringTopContainer.createEl("span", { text: "Dataview Query (optional)", cls: "field-option" }); const dvQueryStringContainer = dvQueryStringTopContainer.createDiv({ cls: "field-container" }); const dvQueryString = new import_obsidian10.TextAreaComponent(dvQueryStringContainer); dvQueryString.inputEl.cols = 50; dvQueryString.inputEl.rows = 4; dvQueryString.setValue(this.field.options.dvQueryString || ""); dvQueryString.inputEl.addClass("full-width"); dvQueryString.onChange((value) => { this.field.options.dvQueryString = value; removeValidationError(dvQueryString); }); } createCustomRenderingContainer(container) { const customRenderingTopContainer = container.createDiv({ cls: "vstacked" }); customRenderingTopContainer.createEl("span", { text: "Alias" }); customRenderingTopContainer.createEl("span", { text: "Personalise the rendering of your links' aliases with a function returning a string ( object is available)", cls: "sub-text" }); customRenderingTopContainer.createEl("code", { text: `function(page) { return ; }` }); const customeRenderingContainer = customRenderingTopContainer.createDiv({ cls: "field-container" }); const customRendering = new import_obsidian10.TextAreaComponent(customeRenderingContainer); customRendering.inputEl.cols = 50; customRendering.inputEl.rows = 4; customRendering.inputEl.addClass("full-width"); customRendering.setValue(this.field.options.customRendering || ""); customRendering.setPlaceholder('Javascript string, the "page" (dataview page type) variable is available\nexample 1: page.file.name\nexample 2: `${page.file.name} of gender ${page.gender}`'); customRendering.onChange((value) => { this.field.options.customRendering = value; removeValidationError(customRendering); }); } createCustomSortingContainer(container) { const customSortingTopContainer = container.createDiv({ cls: "vstacked" }); customSortingTopContainer.createEl("span", { text: "Sorting order" }); customSortingTopContainer.createEl("span", { text: "Personalise the sorting order of your links with a instruction taking 2 files (a, b) and returning -1, 0 or 1", cls: "sub-text" }); customSortingTopContainer.createEl("code", { text: `(a: TFile, b: TFile): number` }); const customSortingContainer = customSortingTopContainer.createDiv({ cls: "field-container" }); const customSorting = new import_obsidian10.TextAreaComponent(customSortingContainer); customSorting.inputEl.cols = 50; customSorting.inputEl.rows = 4; customSorting.inputEl.addClass("full-width"); customSorting.setValue(this.field.options.customSorting || ""); customSorting.setPlaceholder("Javascript instruction, (a: TFile, b: TFile): number\nexample 1 (alphabetical order): a.basename < b.basename ? 1 : -1 \nexample 2 (creation time newer to older): b.stat.ctime - b.stat.ctime"); customSorting.onChange((value) => { this.field.options.customSorting = value; removeValidationError(customSorting); }); } }; } function valueModal5(managedField, plugin) { const base = basicFuzzySuggestModal(managedField, plugin); return class ValueModal extends base { constructor(...rest) { super(plugin.app); this.managedField = managedField; this.managedField.options = getOptions(this.managedField); this.containerEl.addClass("metadata-menu"); const inputContainer = this.containerEl.createDiv({ cls: "suggester-input" }); inputContainer.appendChild(this.inputEl); this.containerEl.find(".prompt").prepend(inputContainer); this.containerEl.createDiv({ cls: "footer-actions" }); cleanActions(this.containerEl, ".footer-actions"); } getItems() { return getFiles(this.managedField); } getItemText(item) { return item.basename; } onChooseItem(item, evt) { throw new Error("Method not implemented."); } onClose() { var _a; (_a = this.managedField.previousModal) == null ? void 0 : _a.open(); } }; } function createDvField4(managedField, dv, p, fieldContainer, attrs = {}) { var _a; attrs.cls = "value-container"; const values = managedField.value; const buildItem = (_value) => fieldContainer.appendChild(dv.el("span", _value || "", attrs)); if (Array.isArray(values)) values.forEach((value) => buildItem(value)); else buildItem(values); const searchBtn = fieldContainer.createEl("button"); (0, import_obsidian10.setIcon)(searchBtn, getIcon(managedField.type)); const spacer = fieldContainer.createEl("div", { cls: "spacer-1" }); const file = managedField.plugin.app.vault.getAbstractFileByPath(p["file"]["path"]); if (file instanceof import_obsidian10.TFile && file.extension == "md") { searchBtn.onclick = () => managedField.openModal(); } else { searchBtn.onclick = async () => { }; } if (!((_a = attrs == null ? void 0 : attrs.options) == null ? void 0 : _a.alwaysOn)) { searchBtn.hide(); spacer.show(); fieldContainer.onmouseover = () => { searchBtn.show(); spacer.hide(); }; fieldContainer.onmouseout = () => { searchBtn.hide(); spacer.show(); }; } } function valueString5(managedField) { if (!isSingleTargeted(managedField)) return ""; if (managedField.value) return getLinksOrTextString(managedField.value, managedField.target); else return ""; } function displayValue5(managedField, container, onClicked) { if (managedField.eF) displayLinksOrText(managedField.value, managedField.eF.file, container, managedField.plugin, onClicked); } function actions5(plugin, field2, file, location, indexedPath) { const iconName = getIcon(field2.type); const action = async () => { var _a; const eF = await getExistingFieldForIndexedPath2(plugin, file, indexedPath); (_a = fieldValueManager(plugin, field2.id, field2.fileClassName, file, eF, indexedPath)) == null ? void 0 : _a.openModal(); }; if (isSuggest(location)) { location.options.push({ id: `update_${field2.name}`, actionLabel: `Update ${field2.name}`, action, icon: iconName }); } else if (isFieldActions(location)) { location.addOption(`field_${field2.id}_update`, iconName, action, `Update ${field2.name}'s value`); } ; } function getOptionsStr5(field2) { return field2.options.dvQueryString || ""; } function buildMarkDownLink(plugin, file, path, subPath, alias) { const destFile = plugin.app.metadataCache.getFirstLinkpathDest(path, file.path); if (destFile) { return plugin.app.fileManager.generateMarkdownLink( destFile, file.path, subPath, alias ); } return ""; } function convertDataviewArrayOfLinkToArrayOfPath(arr) { return arr.reduce((acc, cur) => { if (!cur || !cur.path) return acc; return [...acc, cur.path]; }, []); } function getFiles(managedField) { const options2 = getOptions(managedField); const currentFile = isSingleTargeted(managedField) ? managedField.target : void 0; const dvQueryString = options2.dvQueryString; const getResults = (api) => { try { return new Function("dv", "current", `return ${dvQueryString}`)(api, currentFile ? api.page(currentFile.path) : void 0); } catch (error) { new import_obsidian10.Notice(`Wrong query for field <${managedField.name}> check your settings`, 3e3); } }; const dataview = managedField.plugin.app.plugins.plugins["dataview"]; if (dvQueryString && (dataview == null ? void 0 : dataview.settings.enableDataviewJs) && (dataview == null ? void 0 : dataview.settings.enableInlineDataviewJs)) { try { let results = getResults(dataview.api); if (!results) return []; if (Array.isArray(results.values)) { results = results.values; } const filesPath = results.reduce((a, v) => { if (!v) return a; if (v.path) return [...a, v.path]; if (v.file) return [...a, v.file.path]; if (Array.isArray(v)) return [...a, ...convertDataviewArrayOfLinkToArrayOfPath(v)]; return a; }, []); const sortingMethod = managedField.options.customSorting ? new Function("a", "b", `return ${managedField.options.customSorting}`) : function(a, b) { return a.basename < b.basename ? -1 : 1; }; return managedField.plugin.app.vault.getMarkdownFiles().filter((f) => filesPath.includes(f.path)).sort(sortingMethod); } catch (error) { throw error; } } else { return managedField.plugin.app.vault.getMarkdownFiles(); } } // src/fields/models/Multi.ts var Base5 = class { constructor() { this.type = "Multi"; this.tagName = "multi"; this.icon = "bullet-list"; this.tooltip = "Accepts multiple values from a list"; this.colorClass = "multi"; } }; var DefaultOptions6 = DefaultOptions3; function settingsModal6(Base25) { const base = settingsModal3(Base25); return class SettingsModal extends base { }; } function valueModal6(managedField, plugin) { const base = valueModal3(managedField, plugin); return class ValueModal extends base { constructor(preSelectedOptions) { var _a; super(plugin); this.preSelectedOptions = preSelectedOptions; const initialOptions = isSingleTargeted(managedField) ? managedField.value || [] : []; if (initialOptions && isSingleTargeted(managedField)) { if (Array.isArray(initialOptions)) { this.selectedOptions = initialOptions.filter((i) => !!i).map((item) => { const file = managedField.target; const link = getLink(item, file); if (link) { return buildMarkDownLink(plugin, file, link.path); } else { return item.toString(); } }); this.selectedOptions = initialOptions.filter((i) => !!i).map((item) => item.toString()); } else if (typeof initialOptions === "string" && initialOptions.toString().startsWith("[[")) { this.selectedOptions = initialOptions.split(",").map((item) => item.trim()); } else { const link = getLink(initialOptions, managedField.target); if (link) { this.selectedOptions = [`[[${link.path.replace(".md", "")}]]`]; } else if (typeof initialOptions === "string") { this.selectedOptions = initialOptions.toString().replace(/^\[(.*)\]$/, "$1").split(",").map((item) => item.trim()); } } } else { this.selectedOptions = []; } (_a = this.preSelectedOptions) == null ? void 0 : _a.forEach((item) => { if (!this.selectedOptions.includes(item)) { this.selectedOptions.push(item); } }); this.containerEl.onkeydown = async (e) => { if (e.key == "Enter" && e.altKey) { await this.save(); } }; } async onAdd() { await this.addNewValueToSettings(); await plugin.fieldIndex.indexFields(); this.selectedOptions.push(this.inputEl.value); managedField.value = this.selectedOptions; const modal = getFieldModal(managedField, plugin); modal == null ? void 0 : modal.open(); this.close(); } async save() { this.saved = true; const options2 = this.selectedOptions; managedField.save(options2.join(", ")); this.close(); } renderSelected() { const chooser = this.chooser; const suggestions = chooser.suggestions; const values = chooser.values; suggestions.forEach((s, i) => { if (this.selectedOptions.includes(values[i].toString())) { s.addClass("value-checked"); if (s.querySelectorAll(".icon-container").length == 0) { const iconContainer = s.createDiv({ cls: "icon-container" }); (0, import_obsidian11.setIcon)(iconContainer, "check-circle"); } } else { s.removeClass("value-checked"); s.querySelectorAll(".icon-container").forEach((icon) => icon.remove()); } }); } renderSuggestion(value, el) { el.setText(value); el.addClass("value-container"); const spacer = this.containerEl.createDiv({ cls: "spacer" }); el.appendChild(spacer); if (this.selectedOptions.includes(value.toString())) { el.addClass("value-checked"); const iconContainer = el.createDiv({ cls: "icon-container" }); (0, import_obsidian11.setIcon)(iconContainer, "check-circle"); } this.inputEl.focus(); } selectSuggestion(value, evt) { if (this.selectedOptions.includes(value.toString())) { this.selectedOptions.remove(value.toString()); } else { this.selectedOptions.push(value.toString()); } this.renderSelected(); } buildConfirm(footerActionsContainer) { const infoContainer = footerActionsContainer.createDiv({ cls: "info" }); infoContainer.setText("Alt+Enter to save"); const confirmButton = new import_obsidian11.ButtonComponent(footerActionsContainer); confirmButton.setIcon("checkmark"); confirmButton.onClick(async () => { await this.save(); this.close(); }); } }; } function valueString6(managedField) { return valueString3(managedField); } function displayValue6(managedField, container, onClicked) { return displayValue3(managedField, container, onClicked); } function createDvField5(managedField, dv, p, fieldContainer, attrs = {}) { var _a, _b; let valueHovered = false; let currentValues = []; if (managedField.value) { if (Object.keys(managedField.value).includes("path")) { currentValues = [`[[${managedField.value.path.replace(".md", "")}]]`]; } else if (Array.isArray(managedField.value)) { managedField.value.forEach((item) => { if (Object.keys(item).includes("path")) { currentValues.push(`[[${item.path.replace(".md", "")}]]`); } else { currentValues.push(item.trim()); } }); } else { const value = managedField.value; currentValues = value ? `${value}`.split(",").map((v) => v.trim()) : []; } } const valuesContainer = fieldContainer.createDiv({ cls: "values-container" }); currentValues.forEach((v) => { const valueContainer = valuesContainer.createDiv({ cls: "item-container" }); const valueRemoveBtn = valueContainer.createEl("button"); const valueLabel = valueContainer.createDiv({ cls: "label", text: v }); (0, import_obsidian11.setIcon)(valueRemoveBtn, "cross"); valueRemoveBtn.hide(); valueRemoveBtn.onclick = async () => { const remainingValues = currentValues.filter((cV) => cV !== v).join(", "); managedField.save(remainingValues); }; valueContainer.onmouseover = () => { valueHovered = true; doubleSpacer.hide(); singleSpacer.hide(); valueRemoveBtn.show(); valueLabel.addClass("hovered"); }; valueContainer.onmouseout = () => { valueHovered = false; valueRemoveBtn.hide(); singleSpacer.show(); doubleSpacer.hide(); valueLabel.removeClass("hovered"); }; }); const addBtn = valuesContainer.createEl("button"); (0, import_obsidian11.setIcon)(addBtn, "list-plus"); addBtn.onclick = () => managedField.openModal(); const singleSpacer = valuesContainer.createDiv({ cls: "spacer-1" }); const doubleSpacer = valuesContainer.createDiv({ cls: "spacer-2" }); if (!((_a = attrs == null ? void 0 : attrs.options) == null ? void 0 : _a.alwaysOn)) { addBtn.hide(); fieldContainer.onmouseover = () => { addBtn.show(); doubleSpacer.hide(); if (!valueHovered) singleSpacer.show(); }; fieldContainer.onmouseout = () => { addBtn.hide(); singleSpacer.hide(); doubleSpacer.show(); }; } if (!((_b = attrs == null ? void 0 : attrs.options) == null ? void 0 : _b.alwaysOn)) { singleSpacer.hide(); doubleSpacer.show(); addBtn.hide(); } else { singleSpacer.show(); doubleSpacer.hide(); addBtn.show(); } } function actions6(plugin, field2, file, location, indexedPath) { return actions3(plugin, field2, file, location, indexedPath); } function getOptionsStr6(field2) { return getOptionsStr3(field2); } function validateValue4(managedField) { if (Array.isArray(managedField.value)) { return managedField.value.every((v) => getOptionsList(managedField).includes(v)); } else { return getOptionsList(managedField).includes(managedField.value); } } async function enterFieldSetting5(settingModal, field2, speed = 100) { return enterFieldSetting3(settingModal, field2, speed); } // src/fields/models/Cycle.ts var import_obsidian12 = require("obsidian"); var Base6 = class { constructor() { this.type = "Cycle"; this.tagName = "cycle"; this.icon = "switch"; this.tooltip = "Cycles through values from a list"; this.colorClass = "cycle"; } }; var DefaultOptions7 = DefaultOptions3; function settingsModal7(Base25) { const base = settingsModal3(Base25); return class SettingsModal extends base { createSettingContainer() { const container = this.optionsContainer; const allowNullValueContainer = container.createDiv({ cls: "field-container" }); allowNullValueContainer.createDiv({ cls: "label", text: "Cycle begins by a null value" }); allowNullValueContainer.createDiv({ cls: "spacer" }); this.allowNullToggler = new import_obsidian12.ToggleComponent(allowNullValueContainer).setValue(this.field.options.allowNull || false).onChange((value) => this.field.options.allowNull = value); super.createSettingContainer(); } }; } function valueModal7(managedField, plugin) { const base = valueModal3(managedField, plugin); return class ValueModal extends base { }; } function valueString7(managedField) { return valueString3(managedField); } function displayValue7(managedField, container, onClicked) { return displayValue3(managedField, container, onClicked); } function createDvField6(managedField, dv, p, fieldContainer, attrs = {}) { var _a; fieldContainer.appendChild(dv.el("span", managedField.value || "", attrs)); const spacer = fieldContainer.createEl("div", { cls: "spacer-1" }); const cycleBtn = fieldContainer.createEl("button"); (0, import_obsidian12.setIcon)(cycleBtn, getIcon(managedField.type)); const file = managedField.plugin.app.vault.getAbstractFileByPath(p["file"]["path"]); if (!((_a = attrs == null ? void 0 : attrs.options) == null ? void 0 : _a.alwaysOn)) { cycleBtn.hide(); spacer.show(); fieldContainer.onmouseover = () => { cycleBtn.show(); spacer.hide(); }; fieldContainer.onmouseout = () => { cycleBtn.hide(); spacer.show(); }; } cycleBtn.onclick = async () => { var _a2; managedField.save(getNextOption(managedField)); if (!((_a2 = attrs == null ? void 0 : attrs.options) == null ? void 0 : _a2.alwaysOn)) { cycleBtn.hide(); spacer.show(); } }; } function actions7(plugin, field2, file, location, indexedPath) { const iconName = getIcon(field2.type); const action = async () => { const eF = await getExistingFieldForIndexedPath2(plugin, file, indexedPath); const fieldVM = fieldValueManager(plugin, field2.id, field2.fileClassName, file, eF, indexedPath); if (fieldVM) fieldVM.save(getNextOption(fieldVM)); }; if (isSuggest(location)) { location.options.push({ id: `cycle_${field2.name}`, actionLabel: `Cycle ${field2.name}`, action, icon: iconName }); } else if (isFieldActions(location)) { location.addOption(`field_${field2.id}_shift`, iconName, action, `Cycle ${field2.name}`); } ; } function getOptionsStr7(field2) { return getOptionsStr3(field2); } function validateValue5(managedField) { return getOptionsList2(managedField).includes(managedField.value); } function getOptionsList2(managedField) { return managedField.options.allowNull ? ["", ...getOptionsList(managedField)] : getOptionsList(managedField); } function getNextOption(managedField) { let nextOption; const values = getOptionsList2(managedField); const value = !managedField.value ? "" : managedField.value.toString(); if (values.indexOf(value) === -1) { nextOption = values[0] || ""; } else { nextOption = values[(values.indexOf(value) + 1) % values.length]; } return nextOption; } async function enterFieldSetting6(settingModal, field2, speed = 100) { if (field2.options.allowNull) { settingModal.allowNullToggler.toggleEl.click(); } else if (field2.options.allowNull !== void 0) { settingModal.allowNullToggler.toggleEl.click(); settingModal.allowNullToggler.toggleEl.click(); } return enterFieldSetting3(settingModal, field2, speed); } // src/fields/models/Boolean.ts var import_obsidian13 = require("obsidian"); var Base7 = class { constructor() { this.type = "Boolean"; this.tagName = "boolean"; this.icon = "toggle-left"; this.tooltip = "Accepts true or false"; this.colorClass = "boolean"; } }; var DefaultOptions8 = {}; function settingsModal8(Base25) { return class InputSettingModal extends Base25 { constructor() { super(...arguments); this.createSettingContainer = () => { }; } validateOptions() { return true; } }; } function valueModal8(managedField, plugin) { const base = basicModal(managedField, plugin); return class ValueModal extends base { constructor(...rest) { super(plugin.app); this.managedField = managedField; this.containerEl.addClass("narrow"); this.build(); } build() { const choicesContainer = this.contentEl.createDiv({ cls: "value-container" }); choicesContainer.createDiv({ cls: "spacer" }); const trueButton = new import_obsidian13.ButtonComponent(choicesContainer); trueButton.setButtonText("True"); trueButton.setClass("left"); choicesContainer.createDiv({ cls: "spacer" }); const falseButton = new import_obsidian13.ButtonComponent(choicesContainer); falseButton.setButtonText("False"); choicesContainer.createDiv({ cls: "spacer" }); if (managedField.value) { trueButton.setCta(); falseButton.removeCta(); } else { falseButton.setCta(); trueButton.removeCta(); } falseButton.onClick(() => { managedField.value = "false"; falseButton.setCta(); trueButton.removeCta(); }); trueButton.onClick(() => { managedField.value = "true"; trueButton.setCta(); falseButton.removeCta(); }); this.buildSaveBtn(choicesContainer); } buildSaveBtn(fieldContainer) { fieldContainer.createDiv({ cls: "spacer" }); const infoContainer = fieldContainer.createDiv({ cls: "info" }); infoContainer.setText("Alt+Enter to save"); const saveBtn = new import_obsidian13.ButtonComponent(fieldContainer); saveBtn.setIcon("checkmark"); saveBtn.onClick(() => { this.save(); }); } async save() { this.saved = true; this.managedField.save(); this.close(); } }; } function valueString8(managedField) { return baseGetValueString(managedField); } function displayValue8(managedField, container, onClicked = () => { }) { return baseDisplayValue(managedField, container, onClicked); } function createDvField7(managedField, dv, p, fieldContainer, attrs = {}) { const checkbox = dv.el("input", "", { ...attrs, "type": "checkbox" }); checkbox.checked = managedField.value; fieldContainer.appendChild(checkbox); checkbox.onchange = () => managedField.save((!managedField.value).toString()); } function actions8(plugin, field2, file, location, indexedPath) { const iconName = getIcon(field2.type); const action = async () => { const eF = await getExistingFieldForIndexedPath2(plugin, file, indexedPath); const fieldVM = fieldValueManager(plugin, field2.id, field2.fileClassName, file, eF, indexedPath); if (fieldVM) { fieldVM.value = (!fieldVM.value).toString(); fieldVM.save(); } }; if (isSuggest(location)) { location.options.push({ id: `update_${field2.name}`, actionLabel: `Toggle ${field2.name}`, action, icon: iconName }); } else if (isFieldActions(location)) { location.addOption( `${field2.id}_toggle`, iconName, action, `Toggle ${field2.name}`, field2.fileClassName, file, indexedPath, plugin ); } ; } function getOptionsStr8(field2) { return ""; } function validateValue6(managedField) { return isBoolean(managedField.value); } async function enterFieldSetting7(settingModal, field2, speed = 100) { } // src/fields/models/abstractModels/AbstractDate.ts var import_obsidian14 = require("obsidian"); var DefaultOptions9 = { dateShiftInterval: "1 day", dateFormat: "YYYY-MM-DD", defaultInsertAsLink: false, linkPath: "" }; function settingsModal9(Base25) { return class SettingsModal extends Base25 { createSettingContainer() { var _a; const container = this.optionsContainer; if (!this.field.options.dateFormat) this.field.options.dateFormat = DefaultOptions9.dateFormat; if (!this.field.options.defaultInsertAsLink) this.field.options.defaultInsertAsLink = DefaultOptions9.defaultInsertAsLink; const dateFormatContainer = container.createDiv({ cls: "field-container" }); dateFormatContainer.createEl("span", { text: "Date format", cls: "label" }); const dateExample = dateFormatContainer.createEl("span", { cls: "more-info" }); this.dateFormatInput = new import_obsidian14.TextComponent(dateFormatContainer); const dateFormatInput = this.dateFormatInput; dateFormatInput.inputEl.addClass("with-label"); dateFormatInput.inputEl.addClass("full-width"); dateFormatInput.setValue(this.field.options.dateFormat); dateExample.setText(`${(0, import_obsidian14.moment)().format(dateFormatInput.getValue())}`); dateFormatInput.onChange((value) => { this.field.options.dateFormat = value; dateExample.setText(`${(0, import_obsidian14.moment)().format(value)}`); }); if (this.field.type !== "Time") { const defaultInsertAsLinkContainer = container.createDiv({ cls: "field-container" }); defaultInsertAsLinkContainer.createEl("span", { text: "Insert as link by default", cls: "label" }); defaultInsertAsLinkContainer.createDiv({ cls: "spacer" }); this.defaultInsertAsLink = new import_obsidian14.ToggleComponent(defaultInsertAsLinkContainer); this.defaultInsertAsLink.setValue(this.field.options.defaultInsertAsLink); this.defaultInsertAsLink.onChange((value) => { this.field.options.defaultInsertAsLink = value; }); const dateLinkPathContainer = container.createDiv({ cls: "field-container" }); dateLinkPathContainer.createEl("span", { text: "Link path (optional)", cls: "label" }); this.dateLinkPathInput = new import_obsidian14.TextComponent(dateLinkPathContainer); this.dateLinkPathInput.inputEl.addClass("with-label"); this.dateLinkPathInput.inputEl.addClass("full-width"); this.dateLinkPathInput.setValue(this.field.options.linkPath); this.dateLinkPathInput.onChange((value) => { this.field.options.linkPath = value + (!value.endsWith("/") && !!value.length ? "/" : ""); }); } const dateShiftIntervalContainer = container.createDiv({ cls: "field-container" }); dateShiftIntervalContainer.createEl("span", { text: "Define a shift interval", cls: "label" }); dateShiftIntervalContainer.createDiv({ cls: "spacer" }); this.dateShiftInterval = new import_obsidian14.TextComponent(dateShiftIntervalContainer); this.dateShiftInterval.setPlaceholder("ex: 1 month, 2 days"); this.dateShiftInterval.setValue(this.field.options.dateShiftInterval || DefaultOptions9.dateShiftInterval); this.dateShiftInterval.onChange((value) => { if (!value) { this.field.options.dateShiftInterval = DefaultOptions9.dateShiftInterval; } else { this.field.options.dateShiftInterval = value.toString(); } }); const nextShiftIntervalFieldContainer = container.createDiv({ cls: "field-container" }); nextShiftIntervalFieldContainer.createEl("span", { text: "Field containing shift intervals", cls: "label" }); nextShiftIntervalFieldContainer.createDiv({ cls: "spacer" }); this.nextShiftIntervalField = new import_obsidian14.DropdownComponent(nextShiftIntervalFieldContainer); this.nextShiftIntervalField.addOption("none", "---None---"); const rootFields = getCycleRootFields(this.field); rootFields.forEach((_f) => this.nextShiftIntervalField.addOption(_f.id, _f.name)); const currentField = ((_a = rootFields.find((_f) => _f.name === this.field.options.nextShiftIntervalField)) == null ? void 0 : _a.id) || "none"; this.nextShiftIntervalField.setValue(currentField); this.nextShiftIntervalField.onChange((value) => { var _a2; if (value === "none") { delete this.field.options.nextShiftIntervalField; } else { const field2 = (_a2 = rootFields.find((_f) => _f.id === value)) == null ? void 0 : _a2.name.toString(); this.field.options.nextShiftIntervalField = field2; } }); } validateOptions() { return true; } }; } function getCycleRootFields(field2) { var _a; let rootFields = []; if (field2.fileClassName) { rootFields = ((_a = field2.plugin.fieldIndex.fileClassesFields.get(field2.fileClassName || "")) == null ? void 0 : _a.filter((_f) => _f.isRoot() && _f.name !== field2.name && _f.type === "Cycle")) || []; } else { rootFields = field2.plugin.presetFields.filter((_f) => _f.name !== field2.name && _f.type === "Cycle"); } return rootFields; } function getInputType(type) { switch (type) { case "Date": return "date"; case "DateTime": return "datetime-local"; case "Time": return "time"; default: throw Error("Not implemented"); } } function valueModal9(managedField, plugin) { const base = basicModal(managedField, plugin); return class ValueModal extends base { constructor(...rest) { var _a; super(plugin.app); this.pathTemplateItems = {}; this.pushNextInterval = false; this.managedField = managedField; const initialValue = this.managedField.value || ""; this.initialValue = initialValue ? ((_a = initialValue.toString().replace(/^\[\[/g, "").replace(/\]\]$/g, "").split("|").first()) == null ? void 0 : _a.split("/").last()) || "" : ""; this.insertAsLink = this.managedField.options.defaultInsertAsLink; this.format = this.managedField.options.dateFormat || this.managedField.options.defaultDateFormat; this.value = this.initialValue; } async onOpen() { super.onOpen(); await this.build(); } async build() { this.containerEl.addClass("metadata-menu"); cleanActions(this.contentEl, ".field-container"); cleanActions(this.contentEl, ".field-error"); const fieldContainer = this.contentEl.createDiv({ cls: "field-container" }); await this.buildFields(fieldContainer); this.errorField = this.contentEl.createEl("div", { cls: "field-error" }); this.errorField.hide(); } async buildFields(dateFieldsContainer) { await this.buildInputEl(dateFieldsContainer); this.buildInsertAsLinkButton(dateFieldsContainer); this.buildClearBtn(dateFieldsContainer); this.buildSaveBtn(dateFieldsContainer); } async buildInputEl(container) { [this.currentShift, this.nextIntervalField, this.nextShift] = await shiftDuration(this.managedField); const wrapper = container.createDiv({ cls: "date-input-wrapper" }); this.inputEl = new import_obsidian14.TextComponent(wrapper); this.inputEl.inputEl.addClass("master-input"); this.inputEl.inputEl.addClass(this.managedField.type.toLowerCase()); this.inputEl.inputEl.focus(); this.inputEl.setPlaceholder( this.initialValue ? (0, import_obsidian14.moment)(this.initialValue, this.managedField.options.dateFormat).format(this.managedField.options.dateFormat) : "" ); this.inputEl.onChange((value) => { this.inputEl.inputEl.removeClass("is-invalid"); this.errorField.hide(); this.errorField.setText(""); this.value = value; if (isSingleTargeted(this.managedField)) this.toggleButton(this.shiftFromTodayBtn, value); }); const calendarInput = wrapper.createEl( "input", { type: getInputType(this.managedField.type), cls: this.managedField.type === "Time" ? "time-picker" : "date-picker" } ); calendarInput.value = !this.initialValue ? "" : this.managedField.type === "Time" ? (0, import_obsidian14.moment)(this.initialValue, this.managedField.options.dateFormat).format(this.managedField.options.dateFormat) : (0, import_obsidian14.moment)(this.initialValue, this.managedField.options.dateFormat).format("yyyy-MM-DDTHH:mm"); calendarInput.oninput = (e) => { var _a, _b; const newValue = this.managedField.type === "Time" ? (0, import_obsidian14.moment)((_a = e.target) == null ? void 0 : _a.value, "HH:mm").format(this.format) : (0, import_obsidian14.moment)((_b = e.target) == null ? void 0 : _b.value, "YYYY-MM-DDTHH:mm").format(this.format); this.inputEl.setValue(newValue); this.value = newValue; }; if (isSingleTargeted(this.managedField)) this.buildShiftBtn(container); } buildShiftBtn(container) { this.shiftFromTodayBtn = new import_obsidian14.ButtonComponent(container).setIcon("skip-forward").setTooltip(`Shift ${this.managedField.name} ${this.currentShift || "1 day"} ahead`).onClick((e) => { const newValue = getNewDateValue(this.managedField, this.currentShift); if (!newValue) return; this.inputEl.setValue(newValue); this.value = newValue; this.pushNextInterval = true; this.toggleButton(this.shiftFromTodayBtn, this.inputEl.getValue()); }); } buildPath(value) { let renderedPath = this.managedField.options.linkPath || ""; const templatePathRegex = new RegExp(`\\{\\{(?[^\\}]+?)\\}\\}`, "gu"); const tP = renderedPath.matchAll(templatePathRegex); let next = tP.next(); while (!next.done) { if (next.value.groups) { const pattern = next.value.groups.pattern; this.pathTemplateItems[pattern] = (0, import_obsidian14.moment)(value).format(pattern); } next = tP.next(); } Object.keys(this.pathTemplateItems).forEach((k) => { const fieldRegex = new RegExp(`\\{\\{${k}(:[^\\}]*)?\\}\\}`, "u"); renderedPath = renderedPath.replace(fieldRegex, this.pathTemplateItems[k]); }); return renderedPath; } buildSaveBtn(fieldContainer) { fieldContainer.createDiv({ cls: "spacer" }); const infoContainer = fieldContainer.createDiv({ cls: "info" }); infoContainer.setText("Alt+Enter to save"); const saveBtn = new import_obsidian14.ButtonComponent(fieldContainer); saveBtn.setIcon("checkmark"); saveBtn.onClick(() => { this.save(); }); } async save() { let newValue; if (this.managedField.plugin.app.plugins.enabledPlugins.has("nldates-obsidian") && this.managedField.type === "Date") { try { const nldates = this.managedField.plugin.app.plugins.plugins["nldates-obsidian"]; const parsedDate = nldates.parseDate(`${this.value}`); newValue = parsedDate.date ? parsedDate.moment : (0, import_obsidian14.moment)(`${this.value}`, this.format); } catch (error) { newValue = (0, import_obsidian14.moment)(`${this.value}`, this.format); } } else { newValue = (0, import_obsidian14.moment)(`${this.value}`, this.format); } if (newValue.isValid()) { const renderedPath = this.buildPath(newValue); const destPath = renderedPath || "" + newValue.format(this.format); const sourcePath = isSingleTargeted(this.managedField) ? this.managedField.target.path : destPath; const linkPath = this.managedField.plugin.app.metadataCache.getFirstLinkpathDest(destPath, sourcePath); const formattedValue = this.insertAsLink ? `[[${renderedPath || ""}${newValue.format(this.format)}${linkPath ? "|" + linkPath.basename : ""}]]` : newValue.format(this.format); this.saved = true; this.managedField.save(formattedValue); if (this.nextIntervalField && this.pushNextInterval && this.nextShift && isSingleTargeted(this.managedField)) updateIntervalField(this.managedField, this.nextIntervalField, this.nextShift); this.close(); } else if (!this.value) { this.saved = true; this.managedField.save(""); this.close(); } else { this.errorField.show(); this.errorField.setText(`value must be a valid date`); this.inputEl.inputEl.addClass("is-invalid"); return; } } buildInsertAsLinkButton(container) { const insertAsLinkBtn = new import_obsidian14.ButtonComponent(container); const setLinkBtnIcon = () => { insertAsLinkBtn.setIcon(this.insertAsLink ? "link" : "unlink"); insertAsLinkBtn.setTooltip( this.insertAsLink ? "Click to insert date as text" : "Click to insert date as link" ); }; setLinkBtnIcon(); insertAsLinkBtn.onClick(() => { this.insertAsLink = !this.insertAsLink; setLinkBtnIcon(); }); } buildClearBtn(container) { const clearBtn = new import_obsidian14.ButtonComponent(container); clearBtn.setIcon("eraser"); clearBtn.setTooltip(`Clear ${this.managedField.name}'s date`); clearBtn.onClick(() => { this.value = ""; this.inputEl.setValue(""); this.inputEl.setPlaceholder("Empty"); }); } toggleButton(button, value) { button.setDisabled(!!value); if (value) { button.buttonEl.addClass("disabled"); } else { button.buttonEl.removeClass("disabled"); } } }; } function valueString9(managedField) { let valueString29; const dateFormat = managedField.options.dateFormat; const source = isSingleTargeted(managedField) ? managedField.target : void 0; const dateLink = getLink(managedField.value, source); if (dateLink == null ? void 0 : dateLink.path) { const linkText = dateLink.path.split("/").last() || ""; valueString29 = linkText.replace(/(.*).md/, "$1"); } else { const date = (0, import_obsidian14.moment)(managedField.value, dateFormat); if (date.isValid()) { valueString29 = date.format(managedField.options.dateFormat); } else { valueString29 = managedField.value !== void 0 ? managedField.value : ""; } } return valueString29; } function displayValue9(managedField, container, onClicked) { const dateFormat = managedField.options.dateFormat; const source = isSingleTargeted(managedField) ? managedField.target : void 0; const dateLink = getLink(managedField.value, source); if (dateLink == null ? void 0 : dateLink.path) { const linkText = dateLink.path.split("/").last() || ""; const linkEl = container.createEl("a", { text: linkText.replace(/(.*).md/, "$1") }); linkEl.onclick = () => { managedField.plugin.app.workspace.openLinkText(dateLink.path, (source || dateLink).path, true); onClicked(); }; } else { const date = (0, import_obsidian14.moment)(managedField.value, dateFormat); if (date.isValid()) { const dateText = date.format(managedField.options.dateFormat); if (managedField.options.defaultInsertAsLink) { const rootFolder = managedField.options.linkPath; const linkEl = container.createEl("a", { text: dateText }); linkEl.onclick = () => { const linkPath = `${rootFolder ? rootFolder + "/" : ""}${dateText}.md`; managedField.plugin.app.workspace.openLinkText(linkPath, source ? source.path : linkPath, true); onClicked(); }; } else { container.createDiv({ text: dateText }); } } else { container.createDiv({ text: managedField.value }); } } container.createDiv({}); } function actions9(plugin, field2, file, location, indexedPath) { const dateIconName = getIcon(field2.type); const name = field2.name; const fieldVM = fieldValueManager(plugin, field2.id, field2.fileClassName, file, void 0, indexedPath); if (!fieldVM) return; const getManagedFieldValue = async () => { const eF = await getExistingFieldForIndexedPath2(plugin, file, indexedPath); fieldVM.eF = eF; fieldVM.value = eF == null ? void 0 : eF.value; }; const dateModalAction = async () => { await getManagedFieldValue(); fieldVM.openModal(); }; const shiftDateAction = async () => { await getManagedFieldValue(); await shiftDate(fieldVM); }; const clearDateAction = async () => { await getManagedFieldValue(); fieldVM.save(""); }; if (isSuggest(location)) { location.options.push({ id: `update_${name}`, actionLabel: `Update ${name}`, action: dateModalAction, icon: dateIconName }); if (fieldVM.options.dateShiftInterval || fieldVM.options.nextShiftIntervalField) { location.options.push({ id: `update_${name}`, actionLabel: `Shift ${name} ahead`, action: shiftDateAction, icon: "skip-forward" }); } location.options.push({ id: `clear_${name}`, actionLabel: `Clear ${name}`, action: clearDateAction, icon: "eraser" }); } else if (isFieldActions(location)) { location.addOption(`field_${field2.id}_shift`, "skip-forward", shiftDateAction, `Shift ${name} ahead`); location.addOption(`field_${field2.id}_update`, dateIconName, dateModalAction, `Set ${name}'s date`); } ; } function createDvField8(managedField, dv, p, fieldContainer, attrs = {}) { var _a; attrs.cls = "value-container"; const fieldValue = dv.el("span", managedField.value || "", attrs); const dateBtn = fieldContainer.createEl("button"); (0, import_obsidian14.setIcon)(dateBtn, getIcon(managedField.type)); const spacer = fieldContainer.createDiv({ cls: "spacer-1" }); const shiftBtn = fieldContainer.createEl("button"); (0, import_obsidian14.setIcon)(shiftBtn, "skip-forward"); spacer.setAttr("class", "spacer-2"); const file = managedField.plugin.app.vault.getAbstractFileByPath(p.file.path); if (file instanceof import_obsidian14.TFile && file.extension == "md") { dateBtn.onclick = () => { managedField.openModal(); }; shiftBtn.onclick = () => { if (file) shiftDate(managedField); }; } if (!((_a = attrs == null ? void 0 : attrs.options) == null ? void 0 : _a.alwaysOn)) { dateBtn.hide(); if (shiftBtn) shiftBtn.hide(); spacer.show(); fieldContainer.onmouseover = () => { dateBtn.show(); if (shiftBtn) shiftBtn.show(); spacer.hide(); }; fieldContainer.onmouseout = () => { dateBtn.hide(); if (shiftBtn) shiftBtn.hide(); spacer.show(); }; } fieldContainer.appendChild(fieldValue); fieldContainer.appendChild(dateBtn); if (shiftBtn) fieldContainer.appendChild(shiftBtn); fieldContainer.appendChild(spacer); } function getOptionsStr9(field2) { return field2.options.dateFormat; } function validateValue7(managedField) { var _a, _b; const value = managedField.value; if (!value) { return true; } else { if (typeof value == "string") { return (0, import_obsidian14.moment)( (_a = value.replace(/^\[\[/g, "").replace(/\]\]$/g, "").split("|").first()) == null ? void 0 : _a.split("/").last(), managedField.options.dateFormat ).isValid(); } else { return (0, import_obsidian14.moment)( (_b = value.path.replace(/^\[\[/g, "").replace(/\]\]$/g, "").split("|").first()) == null ? void 0 : _b.split("/").last(), managedField.options.dateFormat ).isValid(); } } } async function shiftDuration(managedField) { var _a; if (!isSingleTargeted(managedField)) return [void 0, void 0, void 0]; const interval = managedField.options.dateShiftInterval || DefaultOptions9.dateShiftInterval; const cycleIntervalField = managedField.options.nextShiftIntervalField; const cycleField = (_a = managedField.plugin.fieldIndex.filesFields.get(managedField.target.path)) == null ? void 0 : _a.find((field2) => field2.name === cycleIntervalField); let nextValue; let currentValue; if (cycleField) { const eF = await Note.getExistingFieldForIndexedPath(managedField.plugin, managedField.target, cycleField.id); currentValue = eF == null ? void 0 : eF.value; const cycleManager = fieldValueManager(managedField.plugin, cycleField.id, managedField.fileClassName, managedField.target, eF, cycleField.id); if (cycleManager) { const options2 = getOptionsList2(cycleManager); if (currentValue) { nextValue = getNextOption(cycleManager); } else { currentValue = options2[0]; nextValue = options2[1]; } } } else { currentValue = interval; } const [_nextShiftNumber, nextShiftPeriod] = currentValue.split(" "); const nextShiftNumber = parseInt(_nextShiftNumber) || 1; if (import_obsidian14.moment.isDuration(import_obsidian14.moment.duration(nextShiftNumber, nextShiftPeriod))) { return [currentValue, cycleField, nextValue]; } else { return [currentValue, cycleField, interval]; } } function getNewDateValue(managedField, currentShift) { if (!isSingleTargeted(managedField)) return; const { dateFormat } = managedField.options; const momentDate = getMomentDate(managedField); if (!momentDate) return; const [_shiftNumber, shiftPeriod] = (currentShift == null ? void 0 : currentShift.split(" ")) || DefaultOptions9.dateShiftInterval; const shiftNumber = parseInt(_shiftNumber) || 1; const _newDate = momentDate.isValid() ? momentDate.add(shiftNumber, shiftPeriod).format(dateFormat) : void 0; return _newDate || (0, import_obsidian14.moment)().format(dateFormat); } function getMomentDate(managedField) { var _a; if (!isSingleTargeted(managedField)) return; const { dateFormat } = managedField.options; const _date = managedField.value; const _dateLink = getLink(_date, managedField.target); const _dateText = _dateLink ? (_a = _dateLink.path.split("/").last()) == null ? void 0 : _a.replace(/(.*).md/, "$1") : _date; return (0, import_obsidian14.moment)(_dateText, dateFormat); } async function updateIntervalField(managedField, nextIntervalField, nextShift) { postValues( managedField.plugin, [ { indexedPath: managedField.indexedPath || managedField.id, payload: { value: managedField.value } }, { indexedPath: nextIntervalField.id, payload: { value: nextShift } } ], managedField.target, managedField.lineNumber, managedField.asList, managedField.asBlockquote ); } async function shiftDate(managedField) { if (!isSingleTargeted(managedField)) return; const { dateFormat, defaultInsertAsLink, linkPath } = managedField.options; const [currentShift, nextIntervalField, nextShift] = await shiftDuration(managedField); const newValue = getNewDateValue(managedField, currentShift); if (!newValue) return; const linkFile = managedField.plugin.app.metadataCache.getFirstLinkpathDest(linkPath || "" + newValue.format(dateFormat), managedField.target.path); const formattedValue = defaultInsertAsLink ? `[[${linkPath || ""}${newValue}${linkFile ? "|" + linkFile.basename : ""}]]` : newValue.format(dateFormat); managedField.value = formattedValue; if (nextIntervalField && nextShift) updateIntervalField(managedField, nextIntervalField, nextShift); else managedField.save(); } async function enterFieldSetting8(settingModal, field2, speed = 100) { var _a; if (field2.options.dateFormat) settingModal.plugin.testRunner.insertInTextComponent(settingModal.dateFormatInput, `${field2.options.dateFormat}`); if (field2.options.dateShiftInterval) settingModal.plugin.testRunner.insertInTextComponent(settingModal.dateShiftInterval, `${field2.options.dateShiftInterval}`); if (field2.options.nextShiftIntervalField) { let cycleField; if (field2.fileClassName) { cycleField = (_a = field2.plugin.fieldIndex.fileClassesFields.get(field2.fileClassName || "")) == null ? void 0 : _a.find((_f) => _f.isRoot() && _f.name !== field2.name && _f.type === "Cycle"); } else { cycleField = field2.plugin.presetFields.find((_f) => _f.name !== field2.name && _f.type === "Cycle"); } if (!cycleField) throw Error("Cycle field for intervals not found"); settingModal.plugin.testRunner.selectInDropDownComponent(settingModal.nextShiftIntervalField, `${cycleField.id}`); } } // src/fields/models/Date.ts var Base8 = class { constructor() { this.type = "Date"; this.tagName = "date"; this.icon = "calendar-with-checkmark"; this.tooltip = "Accepts a date"; this.colorClass = "date"; } }; var DefaultOptions10 = DefaultOptions9; function settingsModal10(Base25) { const base = settingsModal9(Base25); return class SettingsModal extends base { }; } function valueModal10(managedField, plugin) { const base = valueModal9(managedField, plugin); return class ValueModal extends base { }; } function valueString10(managedField) { return valueString9(managedField); } function displayValue10(managedField, container, onClicked) { return displayValue9(managedField, container, onClicked); } function createDvField9(managedField, dv, p, fieldContainer, attrs = {}) { return createDvField8(managedField, dv, p, fieldContainer, attrs); } function actions10(plugin, field2, file, location, indexedPath) { return actions9(plugin, field2, file, location, indexedPath); } function getOptionsStr10(field2) { return getOptionsStr9(field2); } function validateValue8(managedField) { return validateValue7(managedField); } async function enterFieldSetting9(settingModal, field2, speed = 100) { enterFieldSetting8(settingModal, field2, speed); if (field2.options.linkPath) settingModal.plugin.testRunner.insertInTextComponent(settingModal.dateLinkPathInput, `${field2.options.linkPath}`); if (field2.options.defaultInsertAsLink) settingModal.defaultInsertAsLink.toggleEl.click(); } // src/fields/models/DateTime.ts var Base9 = class { constructor() { this.type = "DateTime"; this.tagName = "date"; this.icon = "calendar-clock"; this.tooltip = "Accepts a date with time"; this.colorClass = "date"; } }; var DefaultOptions11 = { ...DefaultOptions9, dateFormat: "YYYY-MM-DD HH:mm" }; function settingsModal11(Base25) { const base = settingsModal9(Base25); return class SettingsModal extends base { }; } function valueModal11(managedField, plugin) { const base = valueModal9(managedField, plugin); return class ValueModal extends base { }; } function valueString11(managedField) { return valueString9(managedField); } function displayValue11(managedField, container, onClicked) { return displayValue9(managedField, container, onClicked); } function createDvField10(managedField, dv, p, fieldContainer, attrs = {}) { return createDvField8(managedField, dv, p, fieldContainer, attrs); } function actions11(plugin, field2, file, location, indexedPath) { return actions9(plugin, field2, file, location, indexedPath); } function getOptionsStr11(field2) { return getOptionsStr9(field2); } function validateValue9(managedField) { return validateValue7(managedField); } async function enterFieldSetting10(settingModal, field2, speed = 100) { enterFieldSetting8(settingModal, field2, speed); if (field2.options.linkPath) settingModal.plugin.testRunner.insertInTextComponent(settingModal.dateLinkPathInput, `${field2.options.linkPath}`); if (field2.options.defaultInsertAsLink) settingModal.defaultInsertAsLink.toggleEl.click(); } // src/fields/models/Time.ts var Base10 = class { constructor() { this.type = "Time"; this.tagName = "time"; this.icon = "clock-4"; this.tooltip = "Accepts a time"; this.colorClass = "time"; } }; var DefaultOptions12 = { ...DefaultOptions9, dateFormat: "HH:mm", dateShiftInterval: "1 hour" }; function settingsModal12(Base25) { const base = settingsModal9(Base25); return class SettingsModal extends base { }; } function valueModal12(managedField, plugin) { const base = valueModal9(managedField, plugin); return class ValueModal extends base { async buildFields(dateFieldsContainer) { await this.buildInputEl(dateFieldsContainer); this.buildClearBtn(dateFieldsContainer); this.buildSaveBtn(dateFieldsContainer); } }; } function valueString12(managedField) { return valueString9(managedField); } function displayValue12(managedField, container, onClicked) { return displayValue9(managedField, container, onClicked); } function createDvField11(managedField, dv, p, fieldContainer, attrs = {}) { return createDvField8(managedField, dv, p, fieldContainer, attrs); } function actions12(plugin, field2, file, location, indexedPath) { return actions9(plugin, field2, file, location, indexedPath); } function getOptionsStr12(field2) { return getOptionsStr9(field2); } function validateValue10(managedField) { return validateValue7(managedField); } async function enterFieldSetting11(settingModal, field2, speed = 100) { enterFieldSetting8(settingModal, field2, speed); } // src/fields/models/File.ts var import_obsidian15 = require("obsidian"); var Base11 = class extends Base4 { constructor() { super(...arguments); this.type = "File"; this.tooltip = "Accepts an internal link"; } }; var DefaultOptions13 = DefaultOptions5; function settingsModal13(Base25) { const base = settingsModal5(Base25); return class SettingsModal extends base { }; } function valueModal13(managedField, plugin) { const base = valueModal5(managedField, plugin); return class ValueModal extends base { constructor(...rest) { var _a; super(); if (isSingleTargeted(this.managedField)) this.selectedFilePath = (_a = getLink(this.managedField.value, this.managedField.target)) == null ? void 0 : _a.path; } async onChooseItem(item) { var _a; this.saved = true; let alias = void 0; const dvApi = (_a = plugin.app.plugins.plugins.dataview) == null ? void 0 : _a.api; if (dvApi && this.managedField.options.customRendering) { alias = new Function("page", `return ${this.managedField.options.customRendering}`)(dvApi.page(item.path)); } const newValue = buildMarkDownLink(plugin, item, item.path, void 0, alias); if (newValue === this.managedField.value) { this.managedField.save(""); } else { this.managedField.save(buildMarkDownLink(plugin, item, item.path, void 0, alias)); } this.close(); } renderSuggestion(value, el) { var _a; const dvApi = (_a = plugin.app.plugins.plugins.dataview) == null ? void 0 : _a.api; if (dvApi && this.managedField.options.customRendering) { const suggestionContainer = el.createDiv({ cls: "item-with-add-on" }); suggestionContainer.createDiv({ text: new Function("page", `return ${this.managedField.options.customRendering}`)(dvApi.page(value.item.path)) }); const filePath = suggestionContainer.createDiv({ cls: "add-on" }); filePath.setText(value.item.path); } else { el.setText(value.item.basename); } el.addClass("value-container"); const spacer = this.containerEl.createDiv({ cls: "spacer" }); el.appendChild(spacer); if (this.selectedFilePath === value.item.path) { el.addClass("value-checked"); const iconContainer = el.createDiv({ cls: "icon-container" }); (0, import_obsidian15.setIcon)(iconContainer, "check-circle"); } this.inputEl.focus(); } }; } function createDvField12(managedField, dv, p, fieldContainer, attrs = {}) { return createDvField4(managedField, dv, p, fieldContainer, attrs); } function valueString13(managedField) { return valueString5(managedField); } function displayValue13(managedField, container, onClicked) { return displayValue5(managedField, container, onClicked); } function actions13(plugin, field2, file, location, indexedPath) { return actions5(plugin, field2, file, location, indexedPath); } function getOptionsStr13(field2) { return getOptionsStr5(field2); } function validateValue11(managedField) { if (Array.isArray(managedField.value) && managedField.value.length == 1) { return getFiles(managedField).map((f) => f.path).includes(managedField.value[0].path); } else if (typeof managedField.value === "string") { return getFiles(managedField).map((f) => f.path).includes(managedField.value); } else if (managedField.value.hasOwnProperty("path")) { return getFiles(managedField).map((f) => f.path).includes(managedField.value.path); } else { return false; } } // src/fields/models/MultiFile.ts var import_obsidian16 = require("obsidian"); var Base12 = class extends Base4 { constructor() { super(...arguments); this.type = "MultiFile"; this.tooltip = "Accepts multiple internal links"; } }; var DefaultOptions14 = DefaultOptions5; function settingsModal14(Base25) { const base = settingsModal5(Base25); return class SettingsModal extends base { }; } function valueModal14(managedField, plugin) { const base = valueModal5(managedField, plugin); return class ValueModal extends base { constructor(...rest) { super(); this.selectedFiles = []; this.initValues(); this.build(); } initValues() { const vault = this.managedField.plugin.app.vault; const initialOptions = this.managedField.value || []; const pushPath = (path) => { const file = vault.getAbstractFileByPath(path); if (file instanceof import_obsidian16.TFile && !this.selectedFiles.map((_f) => _f.path).includes(file.path)) this.selectedFiles.push(file); }; if (initialOptions && isSingleTargeted(this.managedField)) { if (Array.isArray(initialOptions)) { initialOptions.map((item) => { const link = getLink(item, this.managedField.target); if (link) pushPath(link.path); }); } else if (typeof initialOptions === "string") { const links = extractLinks(initialOptions); links.forEach((_link) => { const link = getLink(_link, this.managedField.target); if (link) pushPath(link.path); }); } else { const link = getLink(initialOptions, this.managedField.target); if (link) pushPath(link.path); } } else { this.selectedFiles = []; } } build() { this.containerEl.addClass("metadata-menu"); this.containerEl.onkeydown = async (e) => { if (e.key == "Enter" && e.altKey) { e.preventDefault(); await this.save(); this.close(); } }; cleanActions(this.containerEl, ".footer-actions"); const buttonContainer = this.containerEl.createDiv({ cls: "footer-actions" }); buttonContainer.createDiv({ cls: "spacer" }); const infoContainer = buttonContainer.createDiv({ cls: "info" }); infoContainer.setText("Alt+Enter to save"); const confirmButton = new import_obsidian16.ButtonComponent(buttonContainer); confirmButton.setIcon("checkmark"); confirmButton.onClick(async () => { await this.save(); this.close(); }); const cancelButton = new import_obsidian16.ButtonComponent(buttonContainer); cancelButton.setIcon("cross"); cancelButton.onClick(() => { this.close(); }); const clearButton = new import_obsidian16.ButtonComponent(buttonContainer); clearButton.setIcon("trash"); clearButton.onClick(async () => { await this.clearValues(); this.close(); }); clearButton.buttonEl.addClass("danger"); this.modalEl.appendChild(buttonContainer); } async save() { this.saved = true; const result = this.selectedFiles.map((file) => { var _a; const dvApi = (_a = plugin.app.plugins.plugins.dataview) == null ? void 0 : _a.api; let alias = void 0; if (dvApi && managedField.options.customRendering) { alias = new Function("page", `return ${managedField.options.customRendering}`)(dvApi.page(file.path)); } return buildMarkDownLink(managedField.plugin, file, file.basename, void 0, alias); }); managedField.save(result.join(",")); this.close(); } async clearValues() { managedField.save(""); this.close(); } renderSuggestion(value, el) { var _a; const dvApi = (_a = plugin.app.plugins.plugins.dataview) == null ? void 0 : _a.api; if (dvApi && managedField.options.customRendering) { const suggestionContainer = el.createDiv({ cls: "item-with-add-on" }); suggestionContainer.createDiv({ text: new Function("page", `return ${managedField.options.customRendering}`)(dvApi.page(value.item.path)) }); const filePath = suggestionContainer.createDiv({ cls: "add-on" }); filePath.setText(value.item.path); } else { el.setText(value.item.basename); } el.addClass("value-container"); const spacer = this.containerEl.createDiv({ cls: "spacer" }); el.appendChild(spacer); if (this.selectedFiles.some((file) => file.path === value.item.path)) { el.addClass("value-checked"); const iconContainer = el.createDiv({ cls: "icon-container" }); (0, import_obsidian16.setIcon)(iconContainer, "check-circle"); } } renderSelected() { const chooser = this.chooser; const suggestions = chooser.suggestions; const values = chooser.values; suggestions.forEach((s, i) => { if (this.selectedFiles.some((file) => file.path === values[i].item.path)) { s.addClass("value-checked"); if (s.querySelectorAll(".icon-container").length == 0) { const iconContainer = s.createDiv({ cls: "icon-container" }); (0, import_obsidian16.setIcon)(iconContainer, "check-circle"); } } else { s.removeClass("value-checked"); s.querySelectorAll(".icon-container").forEach((icon) => icon.remove()); } }); } selectSuggestion(value, evt) { if (this.selectedFiles.includes(value.item)) { this.selectedFiles.remove(value.item); } else { this.selectedFiles.push(value.item); } this.renderSelected(); } async onChooseItem(item) { } }; } function createDvField13(managedField, dv, p, fieldContainer, attrs = {}) { return createDvField4(managedField, dv, p, fieldContainer, attrs); } function valueString14(managedField) { return valueString5(managedField); } function displayValue14(managedField, container, onClicked) { return displayValue5(managedField, container, onClicked); } function actions14(plugin, field2, file, location, indexedPath) { return actions5(plugin, field2, file, location, indexedPath); } function getOptionsStr14(field2) { return getOptionsStr5(field2); } function validateValue12(managedField) { const filesPaths = getFiles(managedField).map((f) => f.path); if (!Array.isArray(managedField.value)) { return false; } else { return managedField.value.every((v) => { const link = getLink(v.toString()); if (!link) return false; else return filesPaths.includes(link.path); }); } } // src/fields/models/Media.ts var import_obsidian19 = require("obsidian"); // src/fields/models/abstractModels/AbstractMedia.ts var import_obsidian18 = require("obsidian"); // src/suggester/FolderSuggester.ts var import_obsidian17 = require("obsidian"); var FolderSuggest = class extends TextInputSuggest { constructor(plugin, inputEl) { super(inputEl); this.plugin = plugin; this.inputEl = inputEl; } getSuggestions(inputStr) { const abstractFiles = this.plugin.app.vault.getAllLoadedFiles(); const folders = []; const lowerCaseInputStr = inputStr.toLowerCase(); abstractFiles.forEach((folder) => { if (folder instanceof import_obsidian17.TFolder && folder.path.toLowerCase().contains(lowerCaseInputStr)) { folders.push(folder); } }); return folders; } renderSuggestion(file, el) { el.setText(file.path); } selectSuggestion(file) { this.inputEl.value = file.path; this.inputEl.trigger("input"); this.close(); } }; // src/types/mediaTypes.ts var extensionMediaTypes = { avif: "Image" /* Image */, bmp: "Image" /* Image */, gif: "Image" /* Image */, jpg: "Image" /* Image */, jpeg: "Image" /* Image */, png: "Image" /* Image */, svg: "Image" /* Image */, tif: "Image" /* Image */, tiff: "Image" /* Image */, webp: "Image" /* Image */ }; // src/fields/models/abstractModels/AbstractMedia.ts var commonMediaTypeIcon = (display) => ` `; var filesDisplay = { "list": "list", "card": "card" }; var Base13 = class { constructor() { this.tagName = "file"; this.icon = "paperclip"; this.colorClass = "file"; } }; var DefaultOptions15 = { embed: false, folders: [], display: "card", thumbnailSize: "100" }; function settingsModal15(Base25) { return class SettingModal extends Base25 { constructor() { super(...arguments); this.foldersInputComponents = []; this.createSettingContainer = () => { const container = this.optionsContainer; this.createFoldersListContainer(container); this.createEmbedTogglerContainer(container); this.createFilesDisplaySelectorContainer(container); this.createThumbnailSizeInputContainer(container); this.createCustomSortingContainer(container); }; } validateOptions() { return true; } createCustomSortingContainer(container) { const customSortingTopContainer = container.createDiv({ cls: "vstacked" }); customSortingTopContainer.createEl("span", { text: "Sorting order" }); customSortingTopContainer.createEl("span", { text: "Personalise the sorting order of your links with a instruction taking 2 files (a, b) and returning -1, 0 or 1", cls: "sub-text" }); customSortingTopContainer.createEl("code", { text: `(a: TFile, b: TFile): number` }); const customSortingContainer = customSortingTopContainer.createDiv({ cls: "field-container" }); const customSorting = new import_obsidian18.TextAreaComponent(customSortingContainer); customSorting.inputEl.cols = 50; customSorting.inputEl.rows = 4; customSorting.inputEl.addClass("full-width"); customSorting.setValue(this.field.options.customSorting || ""); customSorting.setPlaceholder("Javascript instruction, (a: TFile, b: TFile): number\nexample 1 (alphabetical order): a.basename < b.basename ? 1 : -1 \nexample 2 (creation time newer to older): b.stat.ctime - b.stat.ctime"); customSorting.onChange((value) => { this.field.options.customSorting = value; removeValidationError(customSorting); }); } createAddButton(valuesListHeader, valuesListBody) { valuesListHeader.createDiv({ cls: "label", text: "Add a folder containing media files" }); valuesListHeader.createDiv({ cls: "spacer" }); const addValue = valuesListHeader.createEl("button"); addValue.type = "button"; addValue.textContent = "Add a value"; addValue.onClickEvent(async (evt) => { evt.preventDefault(); const newKeyNumber = (this.field.options.folders || []).length + 1; this.field.options.folders[newKeyNumber] = ""; this.foldersInputComponents.push(this.createFolderContainer(valuesListBody, newKeyNumber)); }); } createFolderContainer(parentNode, key) { const values = this.field.options.folders || {}; const presetFolder = values[key]; const valueContainer = parentNode.createDiv({ cls: "field-container" }); const input = new import_obsidian18.TextComponent(valueContainer); input.inputEl.addClass("full-width"); input.setValue(presetFolder); input.onChange((value) => { this.field.options.folders[key] = value; removeValidationError(input); }); new FolderSuggest( this.plugin, input.inputEl ); const valueRemoveButton = new import_obsidian18.ButtonComponent(valueContainer); valueRemoveButton.setIcon("trash").onClick((evt) => { evt.preventDefault(); removeValidationError(input); this.field.options.folders = this.field.options.folders.filter((f) => f !== input.getValue()).filter((f) => !!f); parentNode.removeChild(valueContainer); this.foldersInputComponents.remove(input); }); return input; } createFoldersListContainer(parentContainer) { var _a; const valuesListHeader = parentContainer.createDiv({ cls: "field-container" }); const presetFoldersFields = parentContainer.createDiv(); const foldersList = presetFoldersFields.createDiv(); const foldersListContainer = foldersList.createDiv(); this.createAddButton(valuesListHeader, foldersListContainer); (_a = this.field.options.folders) == null ? void 0 : _a.forEach((folder, index) => { this.foldersInputComponents.push(this.createFolderContainer(foldersListContainer, index)); }); return presetFoldersFields; } createEmbedTogglerContainer(container) { const togglerContainer = container.createDiv({ cls: "field-container" }); togglerContainer.createDiv({ cls: "label", text: "Inline thumbnail embedded" }); togglerContainer.createDiv({ cls: "spacer" }); new import_obsidian18.ToggleComponent(togglerContainer).setValue(this.field.options.embed).onChange((value) => this.field.options.embed = value); } createFilesDisplaySelectorContainer(container) { const filesDisplaySelectorContainer = container.createDiv({ cls: "field-container" }); filesDisplaySelectorContainer.createDiv({ cls: "label", text: "File suggest modal display" }); filesDisplaySelectorContainer.createDiv({ cls: "spacer" }); new import_obsidian18.DropdownComponent(filesDisplaySelectorContainer).addOptions(filesDisplay).setValue(this.field.options.display || "list").onChange((value) => this.field.options.display = value); } createThumbnailSizeInputContainer(container) { const thumbnailSizeInputContainer = container.createDiv({ cls: "field-container" }); thumbnailSizeInputContainer.createDiv({ cls: "label", text: "Inline embedded thumbnail height (px): " }); thumbnailSizeInputContainer.createDiv({ cls: "spacer" }); new import_obsidian18.TextComponent(thumbnailSizeInputContainer).setValue(this.field.options.thumbnailSize).onChange((value) => { if (!value) this.field.options.thumbnailSize = ""; else if (isNaN(parseInt(value))) this.field.options.thumbnailSize = "20"; else this.field.options.thumbnailSize = value; }); } }; } function valueModal15(managedField, plugin) { const base = basicFuzzySuggestModal(managedField, plugin); return class ValueModal extends base { constructor(...rest) { var _a; super(plugin.app); this.selectedFiles = []; this.getFiles = () => { const folders = managedField.options.folders; const files = managedField.plugin.app.vault.getFiles().filter((f) => !(folders == null ? void 0 : folders.length) || folders.some((folder) => f.path.startsWith(folder))).filter((f) => !["md", "canvas"].includes(f.extension)); return files; }; this.managedField = managedField; this.containerEl.addClass("metadata-menu"); (_a = this.containerEl.querySelector(".prompt")) == null ? void 0 : _a.addClass( managedField.options.display === "card" ? "media-as-cards" : "media-as-list" ); } getItems() { const sortingMethod = new Function("a", "b", `return ${managedField.options.customSorting}`) || function(a, b) { return a.basename < b.basename ? -1 : 1; }; try { return this.getFiles().sort(sortingMethod); } catch (error) { this.close(); throw error; } } getItemText(item) { return item.basename; } onChooseItem(item, evt) { throw new Error("Method not implemented."); } onClose() { var _a; (_a = this.managedField.previousModal) == null ? void 0 : _a.open(); } renderSuggestion(value, el) { el.addClass("value-container"); const isImage = extensionMediaTypes[value.item.extension] === "Image" /* Image */; const suggestionContainer = el.createDiv({ cls: "media-item" }); const thumbnailContainer = suggestionContainer.createDiv({ cls: "thumbnail-container" }); if (isImage) { const image = thumbnailContainer.createEl("img", { cls: "thumbnail" }); const src = plugin.app.vault.adapter.getResourcePath(value.item.path); if (managedField.options.display === "list") { thumbnailContainer.style.width = "40px"; } image.src = src; } else { thumbnailContainer.innerHTML = commonMediaTypeIcon(managedField.options.display); } const mediaInfoContainer = suggestionContainer.createDiv({ cls: "media-info-container" }); mediaInfoContainer.createDiv({ text: value.item.extension, cls: "chip media-type-container" }); if (this.selectedFiles.some((f) => f.path === value.item.path)) { el.addClass("value-checked"); const iconContainer = mediaInfoContainer.createDiv({ cls: "icon-container" }); (0, import_obsidian18.setIcon)(iconContainer, "check-circle"); } this.inputEl.focus(); const fileName = `${value.item.basename.slice(0, 20).padEnd(value.item.basename.length > 20 ? 23 : 0, ".")}.${value.item.extension}`; suggestionContainer.createDiv({ cls: "file-name", text: fileName }); } }; } function createDvField14(managedField, dv, p, fieldContainer, attrs = {}) { var _a; attrs.cls = "value-container"; const values = managedField.value; const buildItem = (_value) => { if (!_value) return; _value.embed = true; fieldContainer.appendChild(dv.el("span", _value || "", attrs)); }; if (Array.isArray(values)) values.forEach((value) => buildItem(value)); else buildItem(values); const searchBtn = fieldContainer.createEl("button"); (0, import_obsidian18.setIcon)(searchBtn, getIcon(managedField.type)); const spacer = fieldContainer.createEl("div", { cls: "spacer-1" }); const file = managedField.plugin.app.vault.getAbstractFileByPath(p["file"]["path"]); if (file instanceof import_obsidian18.TFile && file.extension == "md") { searchBtn.onclick = () => managedField.openModal(); } else { searchBtn.onclick = async () => { }; } if (!((_a = attrs == null ? void 0 : attrs.options) == null ? void 0 : _a.alwaysOn)) { searchBtn.hide(); spacer.show(); fieldContainer.onmouseover = () => { searchBtn.show(); spacer.hide(); }; fieldContainer.onmouseout = () => { searchBtn.hide(); spacer.show(); }; } } function valueString15(managedField) { if (!isSingleTargeted(managedField)) return ""; if (managedField.value) return getLinksOrTextString(managedField.value, managedField.target); else return ""; } function displayValue15(managedField, container, onClicked) { if (managedField.eF) displayLinksOrText(managedField.value, managedField.eF.file, container, managedField.plugin, onClicked); } function actions15(plugin, field2, file, location, indexedPath) { return actions5(plugin, field2, file, location, indexedPath); } function getOptionsStr15(field2) { const options2 = field2.options; return `${options2.display} | ${options2.embed} | ${options2.size} | ${options2.folders.join(", ")}`; } function getFiles2(managedField) { const folders = managedField.options.folders; const files = managedField.plugin.app.vault.getFiles().filter((f) => !(folders == null ? void 0 : folders.length) || folders.some((folder) => f.path.startsWith(folder))).filter((f) => !["md", "canvas"].includes(f.extension)); return files; } // src/fields/models/Media.ts var Base14 = class extends Base13 { constructor() { super(...arguments); this.type = "Media"; this.tooltip = "Accepts a link to a media file"; } }; var DefaultOptions16 = DefaultOptions15; function settingsModal16(Base25) { const base = settingsModal15(Base25); return class SettingsModal extends base { }; } function valueModal16(managedField, plugin) { const base = valueModal15(managedField, plugin); return class ValueModal extends base { constructor(...rest) { var _a; super(); if (isSingleTargeted(this.managedField)) { const path = (_a = getLink(this.managedField.value, this.managedField.target)) == null ? void 0 : _a.path; if (path) { const file = managedField.plugin.app.vault.getAbstractFileByPath(path); if (file instanceof import_obsidian19.TFile && !this.selectedFiles.map((_f) => _f.path).includes(file.path)) this.selectedFiles.push(file); } } } async onChooseItem(item) { this.saved = true; managedField.save(item.name); } }; } function createDvField15(managedField, dv, p, fieldContainer, attrs = {}) { return createDvField14(managedField, dv, p, fieldContainer, attrs); } function valueString16(managedField) { return valueString15(managedField); } function displayValue16(managedField, container, onClicked) { return displayValue15(managedField, container, onClicked); } function getOptionsStr16(field2) { return getOptionsStr15(field2); } function actions16(plugin, field2, file, location, indexedPath) { return actions15(plugin, field2, file, location, indexedPath); } function validateValue13(managedField) { if (Array.isArray(managedField.value) && managedField.value.length == 1) { return getFiles2(managedField).map((f) => f.path).includes(managedField.value[0].path); } else if (typeof managedField.value === "string") { return getFiles2(managedField).map((f) => f.path).includes(managedField.value); } else if (managedField.value.hasOwnProperty("path")) { return getFiles2(managedField).map((f) => f.path).includes(managedField.value.path); } else { return false; } } // src/fields/models/MultiMedia.ts var import_obsidian20 = require("obsidian"); var Base15 = class extends Base13 { constructor() { super(...arguments); this.type = "MultiMedia"; this.tooltip = "Accepts multiple links to media files"; } }; var DefaultOptions17 = DefaultOptions15; function settingsModal17(Base25) { const base = settingsModal15(Base25); return class SettingsModal extends base { }; } function valueModal17(managedField, plugin) { const base = valueModal15(managedField, plugin); return class ValueModal extends base { constructor(...rest) { super(); this.initValues(); this.build(); } initValues() { const vault = this.managedField.plugin.app.vault; const initialOptions = this.managedField.value || []; const pushPath = (path) => { const file = vault.getAbstractFileByPath(path); if (file instanceof import_obsidian20.TFile && !this.selectedFiles.map((_f) => _f.path).includes(file.path)) this.selectedFiles.push(file); }; if (initialOptions && isSingleTargeted(managedField)) { if (Array.isArray(initialOptions)) { initialOptions.map((item) => { const link = getLink(item, this.managedField.target); if (link) pushPath(link.path); }); } else if (typeof initialOptions === "string") { const links = extractLinks(initialOptions); links.forEach((_link) => { const link = getLink(_link, this.managedField.target); if (link) pushPath(link.path); }); } else { const link = getLink(initialOptions, this.managedField.target); if (link) pushPath(link.path); } } else { this.selectedFiles = []; } } build() { this.containerEl.onkeydown = async (e) => { if (e.key == "Enter" && e.altKey) { e.preventDefault(); await this.save(); this.close(); } }; cleanActions(this.containerEl, ".footer-actions"); const buttonContainer = this.containerEl.createDiv({ cls: "footer-actions" }); buttonContainer.createDiv({ cls: "spacer" }); const infoContainer = buttonContainer.createDiv({ cls: "info" }); infoContainer.setText("Alt+Enter to save"); const confirmButton = new import_obsidian20.ButtonComponent(buttonContainer); confirmButton.setIcon("checkmark"); confirmButton.onClick(async () => { await this.save(); this.close(); }); const cancelButton = new import_obsidian20.ButtonComponent(buttonContainer); cancelButton.setIcon("cross"); cancelButton.onClick(() => { this.close(); }); const clearButton = new import_obsidian20.ButtonComponent(buttonContainer); clearButton.setIcon("trash"); clearButton.onClick(async () => { await this.clearValues(); this.close(); }); clearButton.buttonEl.addClass("danger"); this.modalEl.appendChild(buttonContainer); } async save() { this.saved = true; const result = this.selectedFiles.map((file) => file.name); managedField.save(result.join(", ")); } async clearValues() { this.saved = true; managedField.save(""); this.close(); } renderSelected() { const chooser = this.chooser; const suggestions = chooser.suggestions; const values = chooser.values; suggestions.forEach((s, i) => { if (this.selectedFiles.some((file) => file.path === values[i].item.path)) { s.addClass("value-checked"); if (s.querySelectorAll(".icon-container").length == 0) { const iconContainer = s.createDiv({ cls: "icon-container" }); (0, import_obsidian20.setIcon)(iconContainer, "check-circle"); } } else { s.removeClass("value-checked"); s.querySelectorAll(".icon-container").forEach((icon) => icon.remove()); } }); } selectSuggestion(value, evt) { if (this.selectedFiles.includes(value.item)) { this.selectedFiles.remove(value.item); } else { this.selectedFiles.push(value.item); } this.renderSelected(); } }; } function createDvField16(managedField, dv, p, fieldContainer, attrs = {}) { return createDvField14(managedField, dv, p, fieldContainer, attrs); } function valueString17(managedField) { return valueString15(managedField); } function displayValue17(managedField, container, onClicked) { return displayValue15(managedField, container, onClicked); } function getOptionsStr17(field2) { return getOptionsStr15(field2); } function actions17(plugin, field2, file, location, indexedPath) { return actions15(plugin, field2, file, location, indexedPath); } function validateValue14(managedField) { const filesPaths = getFiles2(managedField).map((f) => f.path); if (!Array.isArray(managedField.value)) { return false; } else { return managedField.value.every((v) => { const link = getLink(v.toString()); if (!link) return false; else return filesPaths.includes(link.path); }); } } // src/fields/models/abstractModels/AbstractCanvas.ts var import_obsidian21 = require("obsidian"); var standardColors = ["1", "2", "3", "4", "5", "6"]; var sides = [ ["top", "chevron-up"], ["right", "chevron-right"], ["bottom", "chevron-down"], ["left", "chevron-left"] ]; var directionOptions = { "incoming": "Incoming", "outgoing": "Outgoing", "bothsides": "Both Sides" }; var DefaultOptions18 = { canvasPath: "" }; function settingsModal18(Base25) { return class SettingsModal extends Base25 { constructor() { super(...arguments); this.buildColorsContainer = (container, colorList, label) => { container.replaceChildren(...[]); container.createEl("span", { text: label, cls: "label" }); container.createDiv({ cls: "spacer" }); const toggleStandardColorButton = (container2, color) => { if (colorList.includes(color)) { container2.addClass("active"); (0, import_obsidian21.setIcon)(container2, "cross"); } else { container2.removeClass("active"); (0, import_obsidian21.setIcon)(container2, "plus"); } ; }; standardColors.forEach((color) => { const colorContainer = container.createDiv({ cls: `node-color color-${color}` }); toggleStandardColorButton(colorContainer, color); colorContainer.onmouseover = () => { colorContainer.setAttr("style", `color: white`); }; colorContainer.onmouseout = () => { colorContainer.removeAttribute("style"); }; colorContainer.onclick = () => { const colors = colorList; if (colors.includes(color)) { colors.remove(color); } else { colors.push(color); } ; toggleStandardColorButton(colorContainer, color); }; }); const toggleAltColors = () => { const altGroupColors = colorList && colorList.filter((color) => !standardColors.includes(color)) || []; altGroupColors.forEach((color) => { const colorContainer = container.createDiv({ cls: `node-color` }); colorContainer.setAttr("style", `background-color: ${color}; color: ${color}`); colorContainer.onmouseover = () => { colorContainer.setAttr("style", `background-color: ${color}; color: white`); }; colorContainer.onmouseout = () => { colorContainer.setAttr("style", `background-color: ${color}; color: ${color}`); }; (0, import_obsidian21.setIcon)(colorContainer, "cross"); colorContainer.onclick = () => { colorList.remove(color); container.removeChild(colorContainer); }; }); }; toggleAltColors(); const altColorPickerContainer = container.createDiv({ cls: `node-color picker` }); const altColorPicker = new import_obsidian21.ColorComponent(altColorPickerContainer); altColorPicker.onChange((value) => { colorList.push(value); this.buildColorsContainer(container, colorList, label); }); }; this.buildEdgeSideContainer = (container, edgeList, label) => { container.createDiv({ cls: "label", text: label }); container.createDiv({ cls: "spacer" }); sides.forEach(([side, iconName]) => { edgeList = edgeList || sides.map((side2) => side2[0]); const edgeSideContainer = container.createDiv({ cls: "edge-side" }); const sideIconContainer = edgeSideContainer.createDiv({ cls: "side-icon" }); (0, import_obsidian21.setIcon)(sideIconContainer, iconName); const sideTogglerContainer = new import_obsidian21.ToggleComponent(edgeSideContainer); sideTogglerContainer.setValue(edgeList.includes(side)); sideTogglerContainer.onChange((value) => value ? edgeList.push(side) : edgeList.remove(side)); }); }; this.buildLabelsContainer = (container, labels, title) => { container.replaceChildren(...[]); container.createDiv({ cls: "label", text: title }); labels.forEach((label) => { const labelContainer = container.createDiv({ cls: "item chip", text: label }); new import_obsidian21.ButtonComponent(labelContainer).setIcon("x-circle").setClass("item-remove").onClick(() => { labels.remove(label); container.removeChild(labelContainer); }); }); }; this.buildNewLabelContainer = (currentLabelsContainer, currentLabelsTitle, newLabelContainer, labels, title) => { newLabelContainer.createDiv({ cls: "label", text: title }); newLabelContainer.createDiv({ cls: "spacer" }); const labelInput = new import_obsidian21.TextComponent(newLabelContainer); const labelValidate = new import_obsidian21.ButtonComponent(newLabelContainer); labelInput.onChange((value) => value ? labelValidate.setCta() : labelValidate.removeCta()); labelValidate.setIcon("plus-circle"); labelValidate.onClick(() => { labels.push(labelInput.getValue()); this.buildLabelsContainer(currentLabelsContainer, labels, currentLabelsTitle); labelInput.setValue(""); labelValidate.removeCta(); }); }; this.createCanvasPathContainer = (container) => { container.createDiv({ text: `Path of the canvas`, cls: "label" }); const canvasPathInput = new import_obsidian21.TextComponent(container); canvasPathInput.inputEl.addClass("full-width"); canvasPathInput.inputEl.addClass("with-label"); new FileSuggest( canvasPathInput.inputEl, this.plugin, "/", "canvas" ); const canvasPath = this.field.options.canvasPath; canvasPathInput.setValue(canvasPath || ""); canvasPathInput.setPlaceholder("Path/of/the/file.canvas"); canvasPathInput.onChange((value) => { removeValidationError(canvasPathInput); this.field.options.canvasPath = value; }); this.canvasPathInput = canvasPathInput; }; this.createDirectionContainer = (container, title) => { container.createDiv({ text: title, cls: "label" }); container.createDiv({ cls: "spacer" }); const directionSelection = new import_obsidian21.DropdownComponent(container); Object.entries(directionOptions).forEach(([direction, label]) => directionSelection.addOption(direction, label)); directionSelection.setValue(this.field.options.direction || "incoming"); directionSelection.onChange((value) => this.field.options.direction = value); }; this.createDvQueryContainer = (container, title) => { container.createEl("span", { text: title }); container.createEl("span", { text: "Dataview query returning a list of files ( object is available)", cls: "sub-text" }); const filesFromDVQueryContainer = container.createDiv({ cls: "field-container" }); const filesFromDVQuery = new import_obsidian21.TextAreaComponent(filesFromDVQueryContainer); filesFromDVQuery.inputEl.addClass("full-width"); filesFromDVQuery.inputEl.cols = 65; filesFromDVQuery.inputEl.rows = 3; filesFromDVQuery.setPlaceholder("ex: dv.pages('#student')"); filesFromDVQuery.setValue(this.field.options.filesFromDVQuery || ""); filesFromDVQuery.onChange((value) => { this.field.options.filesFromDVQuery = value; }); }; } createSettingContainer() { } validateOptions() { return true; } }; } function validateValue15(managedField) { var _a; let error = false; if (!((_a = managedField.options.canvasPath) == null ? void 0 : _a.endsWith(".canvas"))) { error = true; } return !error; } function valueString18(managedField) { if (!isSingleTargeted(managedField)) return ""; const result = []; const value = managedField.value; const values = Array.isArray(value) ? value : [value]; values.forEach((value2, i) => { const link = getLink(value2, managedField.target); if (link == null ? void 0 : link.path) { const linkText = link.path.split("/").last() || ""; result.push(linkText.replace(/(.*).md/, "$1")); } else { result.push(value2); } if (i < values.length - 1) { result.push(" | "); } }); return result.join(""); } function displayValue18(managedField, container, onClicked) { if (!isSingleTargeted(managedField)) return; const value = managedField.value; const values = Array.isArray(value) ? value : [value]; values.forEach((value2, i) => { const link = getLink(value2, managedField.target); if (link == null ? void 0 : link.path) { const linkText = link.path.split("/").last() || ""; const linkEl = container.createEl("a", { text: linkText.replace(/(.*).md/, "$1") }); linkEl.onclick = () => { managedField.plugin.app.workspace.openLinkText(value2.path, managedField.target.path, true); onClicked(); }; } else { container.createDiv({ text: value2 }); } if (i < values.length - 1) { container.createEl("span", { text: " | " }); } }); container.createDiv(); } // src/fields/models/Canvas.ts var Base16 = class { constructor() { this.type = "Canvas"; this.tagName = "canvas-links"; this.icon = "layout-dashboard"; this.tooltip = "Updates with links in canvas"; this.colorClass = "file"; } }; var DefaultOptions19 = { ...DefaultOptions18, direction: "bothsides", nodeColors: [], edgeColors: [], edgeFromSides: [], edgeToSides: [], edgeLabels: [] }; function settingsModal19(Base25) { const base = settingsModal18(Base25); return class SettingModal extends base { //options //initial values createSettingContainer() { const container = this.optionsContainer; const options2 = this.field.options; options2.direction = options2.direction || "bothsides"; options2.nodeColors = options2.nodeColors || []; options2.edgeColors = options2.edgeColors || []; options2.edgeFromSides = options2.edgeFromSides || []; options2.edgeToSides = options2.edgeToSides || []; options2.edgeLabels = options2.edgeLabels || []; const canvasPathContainer = container.createDiv({ cls: "field-container" }); container.createEl("hr"); const directionContainer = container.createDiv({ cls: "field-container" }); const edgeColorsContainer = container.createDiv({ cls: "field-container colors" }); const edgeFromSidesContainer = container.createDiv({ cls: "field-container edges" }); container.createDiv({ cls: "sub-text", text: "No edge selected is equivalent to all edges selected" }); const edgeToSidesContainer = container.createDiv({ cls: "field-container egdes" }); container.createDiv({ cls: "sub-text", text: "No edge selected is equivalent to all edges selected" }); const edgeLabelsContainer = container.createDiv({ cls: "field-container labels" }); const newEdgeLabelContainer = container.createDiv({ cls: "field-container" }); container.createEl("hr"); const nodeColorsContainer = container.createDiv({ cls: "field-container colors" }); const filesFromDVQueryTopContainer = container.createDiv({ cls: "vstacked" }); this.createCanvasPathContainer(canvasPathContainer); this.createDirectionContainer(directionContainer, `Direction of the edges pointing to those nodes`); this.createDvQueryContainer(filesFromDVQueryTopContainer, "Matching files"); this.buildColorsContainer(nodeColorsContainer, options2.nodeColors, "Node matching colors:"); this.buildColorsContainer(edgeColorsContainer, options2.edgeColors, "Edge matching colors:"); this.buildEdgeSideContainer(edgeFromSidesContainer, options2.edgeFromSides, "Edges matchin From side:"); this.buildEdgeSideContainer(edgeToSidesContainer, options2.edgeToSides, "Edges matchin To side:"); this.buildLabelsContainer(edgeLabelsContainer, options2.edgeLabels, "Edges matching labels: "); this.buildNewLabelContainer(edgeLabelsContainer, "Edges matching labels: ", newEdgeLabelContainer, options2.edgeLabels, "Add a new matching edge label"); } }; } function valueString19(managedField) { return valueString18(managedField); } function displayValue19(managedField, container, onClicked) { return displayValue18(managedField, container, onClicked); } function validateValue16(managedField) { return validateValue15(managedField); } // src/fields/models/CanvasGroup.ts var Base17 = class { constructor() { this.type = "CanvasGroup"; this.tagName = "canvas-links"; this.icon = "box-select"; this.tooltip = "Updates with groups in canvas"; this.colorClass = "file"; } }; var DefaultOptions20 = { ...DefaultOptions18, groupColors: [], groupLabels: [] }; function settingsModal20(Base25) { const base = settingsModal18(Base25); return class SettingModal extends base { //options //initial values createSettingContainer() { const container = this.optionsContainer; const options2 = this.field.options; options2.groupColors = options2.groupColors || []; options2.groupLabels = options2.groupLabels || []; const canvasPathContainer = container.createDiv({ cls: "field-container" }); container.createEl("hr"); const groupColorsContainer = container.createDiv({ cls: "field-container colors" }); const groupLabelsContainer = container.createDiv({ cls: "field-container labels" }); const newLabelContainer = container.createDiv({ cls: "field-container" }); this.createCanvasPathContainer(canvasPathContainer); this.buildColorsContainer(groupColorsContainer, options2.groupColors, "Groups matching colors:"); this.buildLabelsContainer(groupLabelsContainer, options2.groupLabels, "Groups matching labels: "); this.buildNewLabelContainer(groupLabelsContainer, "Groups matching labels: ", newLabelContainer, options2.groupLabels, "Add a new matching group name"); } }; } function valueString20(managedField) { return valueString18(managedField); } function displayValue20(managedField, container, onClicked) { return displayValue18(managedField, container, onClicked); } function validateValue17(managedField) { return validateValue15(managedField); } // src/fields/models/CanvasGroupLink.ts var Base18 = class { constructor() { this.type = "CanvasGroup"; this.tagName = "canvas-links"; this.icon = "box-select"; this.tooltip = "Updates with groups in canvas"; this.colorClass = "file"; } }; var DefaultOptions21 = { ...DefaultOptions18, groupColors: [], groupLabels: [], direction: "bothsides", nodeColors: [], edgeColors: [], edgeFromSides: [], edgeToSides: [], edgeLabels: [] }; function settingsModal21(Base25) { const base = settingsModal18(Base25); return class SettingModal extends base { //options //initial values createSettingContainer() { const container = this.optionsContainer; const options2 = this.field.options; options2.groupColors = options2.groupColors || []; options2.nodeColors = options2.nodeColors || []; options2.edgeColors = options2.edgeColors || []; options2.edgeFromSides = options2.edgeFromSides || []; options2.edgeToSides = options2.edgeToSides || []; options2.groupLabels = options2.groupLabels || []; options2.edgeLabels = options2.edgeLabels || []; options2.direction = options2.direction || "bothsides"; const canvasPathContainer = container.createDiv({ cls: "field-container" }); const groupColorsContainer = container.createDiv({ cls: "field-container colors" }); const groupLabelsContainer = container.createDiv({ cls: "field-container labels" }); const newGroupLabelContainer = container.createDiv({ cls: "field-container" }); container.createEl("hr"); const directionContainer = container.createDiv({ cls: "field-container" }); const edgeColorsContainer = container.createDiv({ cls: "field-container colors" }); const edgeFromSidesContainer = container.createDiv({ cls: "field-container edges" }); container.createDiv({ cls: "sub-text", text: "No edge selected is equivalent to all edges selected" }); const edgeToSidesContainer = container.createDiv({ cls: "field-container egdes" }); container.createDiv({ cls: "sub-text", text: "No edge selected is equivalent to all edges selected" }); const edgeLabelsContainer = container.createDiv({ cls: "field-container labels" }); const newEdgeLabelContainer = container.createDiv({ cls: "field-container" }); container.createEl("hr"); const nodeColorsContainer = container.createDiv({ cls: "field-container colors" }); const filesFromDVQueryTopContainer = container.createDiv({ cls: "vstacked" }); const groupLabelsTitle = "Groups matching labels: "; const edgeLabelsTitle = "Edges matching labels: "; this.createCanvasPathContainer(canvasPathContainer); this.createDirectionContainer(directionContainer, `Direction of the edges pointing to those groups`); this.createDvQueryContainer(filesFromDVQueryTopContainer, "Matching files connected to those groups"); this.buildColorsContainer(groupColorsContainer, options2.groupColors, "Groups matching colors:"); this.buildColorsContainer(nodeColorsContainer, options2.nodeColors, "Groups' connected nodes matching colors:"); this.buildColorsContainer(edgeColorsContainer, options2.edgeColors, "Groups' edges matching colors:"); this.buildLabelsContainer(groupLabelsContainer, options2.groupLabels, groupLabelsTitle); this.buildLabelsContainer(edgeLabelsContainer, options2.edgeLabels, edgeLabelsTitle); this.buildEdgeSideContainer(edgeFromSidesContainer, options2.edgeFromSides, "Groups' edges matchin From side:"); this.buildEdgeSideContainer(edgeToSidesContainer, options2.edgeToSides, "Groups' edges matchin To side:"); this.buildNewLabelContainer(groupLabelsContainer, groupLabelsTitle, newGroupLabelContainer, options2.groupLabels, "Add a new matching group name"); this.buildNewLabelContainer(edgeLabelsContainer, edgeLabelsTitle, newEdgeLabelContainer, options2.edgeLabels, "Add a new matching edge label"); } }; } function valueString21(managedField) { return valueString18(managedField); } function displayValue21(managedField, container, onClicked) { return displayValue18(managedField, container, onClicked); } function validateValue18(managedField) { return validateValue15(managedField); } // src/fields/models/Formula.ts var import_obsidian24 = require("obsidian"); // src/commands/updateFormulas.ts var import_obsidian23 = require("obsidian"); // src/commands/updateLookups.ts var import_obsidian22 = require("obsidian"); // src/utils/array.ts var compareArrays = (a, b) => { return a.length === b.length && a.every((element, index) => element === b[index]); }; // src/commands/updateLookups.ts function arraysAsStringAreEqual(a, b) { const aAsArray = typeof a === "string" ? a.split(",").map((v) => v.trim()) : Array.isArray(a) ? a : []; const bAsArray = typeof b === "string" ? b.split(",").map((v) => v.trim()) : Array.isArray(b) ? b : []; return aAsArray.every((item) => bAsArray.includes(item)) && bAsArray.every((item) => aAsArray.includes(item)); } function renderValue(field2, pages, plugin, tFile, renderingErrors) { let newValue = ""; switch (field2.options.outputType) { case "LinksList" /* LinksList */: case "LinksBulletList" /* LinksBulletList */: { const newValuesArray = pages == null ? void 0 : pages.map((dvFile) => { return buildMarkDownLink(plugin, tFile, dvFile.file.path); }); newValue = (newValuesArray || []).join(", "); } break; case "CustomList" /* CustomList */: case "CustomBulletList" /* CustomBulletList */: { const renderingFunction = new Function("page", `return ${field2.options.customListFunction}`); const newValuesArray = pages == null ? void 0 : pages.map((dvFile) => { try { return renderingFunction(dvFile); } catch (e) { plugin.fieldIndex.fileLookupFieldsStatus.set(`${tFile.path}__related__${field2.fileClassName}___${field2.name}`, "error" /* error */); if (!renderingErrors.includes(field2.name)) renderingErrors.push(field2.name); return ""; } }); newValue = (newValuesArray || []).join(", "); } break; case "CustomSummarizing" /* CustomSummarizing */: { const customSummarizingFunction = field2.options.customSummarizingFunction; const summarizingFunction = new Function( "pages", customSummarizingFunction.replace(/\{\{summarizedFieldName\}\}/g, field2.options.summarizedFieldName) ); try { newValue = summarizingFunction(pages).toString(); } catch (e) { plugin.fieldIndex.fileLookupFieldsStatus.set(`${tFile.path}__related__${field2.fileClassName}___${field2.name}`, "error" /* error */); if (!renderingErrors.includes(field2.name)) renderingErrors.push(field2.name); newValue = ""; } } break; case "BuiltinSummarizing" /* BuiltinSummarizing */: { const builtinFunction = field2.options.builtinSummarizingFunction; const summarizingFunction = new Function( "pages", BuiltinSummarizingFunction[builtinFunction].replace(/\{\{summarizedFieldName\}\}/g, field2.options.summarizedFieldName) ); try { newValue = summarizingFunction(pages).toString(); } catch (e) { if (!renderingErrors.includes(field2.name)) renderingErrors.push(field2.name); newValue = ""; } } break; default: break; } return newValue; } function cleanRemovedLookupItemsFromIndex(plugin) { var _a; const f = plugin.fieldIndex; for (let id of f.fileLookupFieldLastValue.keys()) { const matchRegex = /(?.*)__related__(?.*)___(?.*)/; const { filePath, fieldName, fileClassName } = ((_a = id.match(matchRegex)) == null ? void 0 : _a.groups) || {}; const file = plugin.app.vault.getAbstractFileByPath(filePath); if (!(file instanceof import_obsidian22.TFile)) continue; const dvPage = f.dv.api.page(filePath); const currentLinks = (Array.isArray(dvPage[fieldName]) ? dvPage[fieldName] : dvPage[fieldName] ? [dvPage[fieldName]] : []).map((p) => p == null ? void 0 : p.path); const indexedLinks = (extractLinks(f.fileLookupFieldLastValue.get(id) || "") || []).map((l) => { var _a2; return ((_a2 = getLink(l)) == null ? void 0 : _a2.path) || ""; }); if (!compareArrays(currentLinks, indexedLinks)) { f.fileLookupFieldLastValue.set(id, currentLinks.filter((l) => !!l).map((l) => buildMarkDownLink(plugin, file, l)).join(", ")); } } } async function updateLookups(plugin, forceUpdateOne, forceUpdateAll = false) { const start2 = Date.now(); const f = plugin.fieldIndex; const renderingErrors = []; const payloads = {}; const updatedFields = []; await Promise.all([...f.fileLookupFiles.keys()].map(async (lookupFileId) => { var _a, _b; const matchRegex = /(?.*)__related__(?.*)___(?.*)/; const { filePath, fieldName } = ((_a = lookupFileId.match(matchRegex)) == null ? void 0 : _a.groups) || {}; const file = plugin.app.vault.getAbstractFileByPath(filePath); if (!file || !(file instanceof import_obsidian22.TFile)) return; payloads[filePath] = payloads[filePath] || []; let newValue = ""; const pages = f.fileLookupFiles.get(lookupFileId); const field2 = (_b = f.filesFields.get(filePath)) == null ? void 0 : _b.find((field3) => field3.name == fieldName); if (field2) { const outputType = field2.options.outputType; if (!f.fileLookupFieldLastOutputType.get(lookupFileId)) f.fileLookupFieldLastOutputType.set(lookupFileId, outputType); newValue = renderValue(field2, pages, plugin, file, renderingErrors); const currentValue = f.fileLookupFieldLastValue.get(lookupFileId); const shouldCheckForUpdate = field2.options.autoUpdate || field2.options.autoUpdate === void 0 || forceUpdateAll || //field is autoUpdated OR //field is not autoupdated and we have to check for request to update this one (forceUpdateOne == null ? void 0 : forceUpdateOne.file.path) === file.path && (forceUpdateOne == null ? void 0 : forceUpdateOne.fieldName) === field2.name; const valueHasChanged = !currentValue && newValue !== "" || !arraysAsStringAreEqual(currentValue || "", newValue); const formatHasChanged = outputType !== f.fileLookupFieldLastOutputType.get(lookupFileId); if (f.lastTimeBeforeResolving && file.stat.mtime < f.lastTimeBeforeResolving && file.stat.mtime > (f.lastDVUpdatingTime || 0)) { return; } if (valueHasChanged || formatHasChanged) { f.fileLookupFieldsStatus.set(`${filePath}__${fieldName}`, "changed" /* changed */); } if (shouldCheckForUpdate) { f.fileLookupFieldLastValue.set(lookupFileId, newValue); f.fileLookupFieldLastOutputType.set(lookupFileId, outputType); } if (shouldCheckForUpdate && (valueHasChanged || formatHasChanged)) { payloads[filePath].push({ indexedPath: field2.id, payload: { value: newValue } }); updatedFields.push(`${filePath}__${fieldName}`); } if (!valueHasChanged && !formatHasChanged) { f.fileLookupFieldsStatus.set(`${filePath}__${fieldName}`, "upToDate" /* upToDate */); } } })); Object.entries(payloads).forEach(async ([filePath, fieldsPayload]) => { f.pushPayloadToUpdate(filePath, fieldsPayload); }); } // src/commands/updateFormulas.ts function cleanRemovedFormulasFromIndex(plugin) { var _a, _b; const f = plugin.fieldIndex; for (let id of f.fileFormulaFieldLastValue.keys()) { const matchRegex = /(?.*)__calculated__(?.*)___(?.*)/; const { filePath, fileClassName, fieldName } = ((_a = id.match(matchRegex)) == null ? void 0 : _a.groups) || {}; const existingFormulaFieldWithNameAndFileClassName = (_b = f.filesFields.get(filePath)) == null ? void 0 : _b.find( (field2) => field2.name === fieldName && (field2.fileClassName === void 0 && fileClassName === "presetField" || field2.fileClassName === fileClassName) ); const dvPage = f.dv.api.page(filePath); if (dvPage === void 0 || dvPage[fieldName] === void 0 || !existingFormulaFieldWithNameAndFileClassName) { f.fileFormulaFieldLastValue.delete(id); } } } async function updateFormulas(plugin, forceUpdateOne, forceUpdateAll = false) { var _a, _b; const start2 = Date.now(); MDM_DEBUG && console.log("start update formulas", plugin.fieldIndex.lastRevision, "->", (_a = plugin.fieldIndex.dv) == null ? void 0 : _a.api.index.revision); const f = plugin.fieldIndex; const fileFormulasFields = /* @__PURE__ */ new Map(); [...f.filesLookupAndFormulaFieldsExists].forEach(([filePath, fields]) => { fields.filter((field2) => field2.type === "Formula").forEach((field2) => { const fileFormulaField = `${filePath}__calculated__${field2.fileClassName || "presetField"}___${field2.name}`; fileFormulasFields.set(fileFormulaField, field2); }); }); await Promise.all([...fileFormulasFields].map(async ([id, field2]) => { var _a2; const matchRegex = /(?.*)__calculated__(?.*)___(?.*)/; const { filePath, fileClassName, fieldName } = ((_a2 = id.match(matchRegex)) == null ? void 0 : _a2.groups) || {}; const shouldUpdate = forceUpdateAll || (forceUpdateOne == null ? void 0 : forceUpdateOne.file.path) === filePath && (forceUpdateOne == null ? void 0 : forceUpdateOne.fieldName) === fieldName || field2.options.autoUpdate === true; const _file = plugin.app.vault.getAbstractFileByPath(filePath); if (!_file || !(_file instanceof import_obsidian23.TFile)) return; const currentValue = `${f.fileFormulaFieldLastValue.get(id) || ""}`; try { const dvFile = f.dv.api.page(filePath); const newValue = new Function("current, dv", `return ${field2.options.formula}`)(dvFile, f.dv.api).toString(); const valueHasChanged = currentValue === void 0 && newValue !== "" || !arraysAsStringAreEqual(currentValue, newValue) || currentValue !== newValue; if (!valueHasChanged) { f.fileFormulaFieldsStatus.set(`${filePath}__${fieldName}`, "upToDate" /* upToDate */); return; } else { if (!shouldUpdate) { f.fileFormulaFieldsStatus.set(`${filePath}__${field2.name}`, "changed" /* changed */); } else { f.pushPayloadToUpdate(filePath, [{ indexedPath: field2.id, payload: { value: newValue } }]); f.fileFormulaFieldLastValue.set(id, newValue); f.fileFormulaFieldsStatus.set(`${filePath}__${field2.name}`, "upToDate" /* upToDate */); } } } catch (e) { f.fileFormulaFieldsStatus.set(`${filePath}__${field2.name}`, "error" /* error */); } })); MDM_DEBUG && console.log("finished update formulas", plugin.fieldIndex.lastRevision, "->", (_b = plugin.fieldIndex.dv) == null ? void 0 : _b.api.index.revision, `${Date.now() - start2}ms`); cleanRemovedFormulasFromIndex(plugin); } // src/fields/models/Formula.ts var Base19 = class { constructor() { this.type = "Formula"; this.tagName = "formula"; this.icon = "function-square"; this.tooltip = "Accepts a formula"; this.colorClass = "lookup"; } }; var DefaultOptions22 = {}; function settingsModal22(Base25) { return class InputSettingModal extends Base25 { constructor() { super(...arguments); this.createSettingContainer = () => { const container = this.optionsContainer; const autoUpdateTopContainer = container.createDiv({ cls: "vstacked" }); const autoUpdateContainer = autoUpdateTopContainer.createDiv({ cls: "field-container" }); autoUpdateContainer.createEl("span", { text: "Auto update this field ", cls: "label" }); autoUpdateContainer.createDiv({ cls: "spacer" }); const autoUpdate = new import_obsidian24.ToggleComponent(autoUpdateContainer); autoUpdateTopContainer.createEl("span", { text: "This could lead to latencies depending on the queries", cls: "sub-text warning" }); if (this.field.options.autoUpdate === void 0) this.field.options.autoUpdate = false; autoUpdate.setValue(this.field.options.autoUpdate); autoUpdate.onChange((value) => { this.field.options.autoUpdate = value; }); const formulaTopContainer = container.createDiv({ cls: "vstacked" }); formulaTopContainer.createEl("span", { text: "javascript formula", cls: "label" }); formulaTopContainer.createEl("span", { text: "current and dv variables are available", cls: "sub-text" }); const formulaContainer = formulaTopContainer.createDiv({ cls: "field-container" }); const formula = new import_obsidian24.TextAreaComponent(formulaContainer); formula.inputEl.addClass("full-width"); formula.inputEl.cols = 50; formula.inputEl.rows = 4; formula.setValue(this.field.options.formula || ""); formula.setPlaceholder("example: current.apple + current.bananas - 3"); formula.onChange((value) => { this.field.options.formula = value; removeValidationError(formula); }); }; } validateOptions() { return true; } }; } function valueString22(managedField) { var _a, _b; if (!isSingleTargeted(managedField)) return ""; const fileClassName = ((_b = (_a = managedField.plugin.fieldIndex.filesFields.get(managedField.target.path)) == null ? void 0 : _a.find((f) => f.id === managedField.id)) == null ? void 0 : _b.fileClassName) || "presetField"; return managedField.plugin.fieldIndex.fileFormulaFieldLastValue.get(`${managedField.target.path}__calculated__${fileClassName}___${managedField.name}`) || ""; } function displayValue22(managedField, container, onClicked = () => { }) { if (!isSingleTargeted(managedField)) return; container.createDiv({ text: valueString22(managedField) }); } function actions18(plugin, field2, file, location, indexedPath) { const name = field2.name; const f = plugin.fieldIndex; const id = `${file.path}__${name}`; const status = f.fileFormulaFieldsStatus.get(id) || "changed" /* changed */; const action = async () => { await updateFormulas(plugin, { file, fieldName: name }); f.applyUpdates(); }; if (field2.options.autoUpdate === false || !plugin.settings.isAutoCalculationEnabled) { const icon = statusIcon[status]; if (isSuggest(location) && ["changed" /* changed */, "mayHaveChanged" /* mayHaveChanged */].includes(status)) { location.options.push({ id: `update_${name}`, actionLabel: `Update ${name}`, action, icon }); } else if (isFieldActions(location) && ["changed" /* changed */, "mayHaveChanged" /* mayHaveChanged */].includes(status)) { location.addOption(`field_${field2.id}_udapte`, icon, action, `Update ${name}'s value`); } else if (isFieldActions(location) && status === "upToDate" /* upToDate */) { location.addOption(`field_${field2.id}_udapte`, icon, () => { }, `${name} is up to date`); } else if (isFieldActions(location) && status === "error" /* error */) { location.addOption(`field_${field2.id}_udapte`, icon, () => { }, `${name} has an error`); } } else if (isFieldActions(location)) { const icon = status === "error" /* error */ ? statusIcon["error"] : "server-cog"; location.addOption(`field_${field2.id}_update`, icon, () => { }, `${name} is auto-updated`, "disabled"); } } function validateValue19(managedField) { return true; } // src/fields/models/Lookup.ts var import_obsidian25 = require("obsidian"); // src/commands/resolveLookups.ts function resolveLookups(plugin) { var _a, _b; const index = plugin.fieldIndex; const lookupQueryResults = /* @__PURE__ */ new Map(); [...index.lookupQueries].forEach(([lookupName, field2]) => { const queryRelatedDVFiles = new Function("dv", `return ${field2.options.dvQueryString}`)(index.dv.api).values; lookupQueryResults.set(lookupName, queryRelatedDVFiles); }); [...index.filesLookupAndFormulaFieldsExists].forEach(([filePath, fields]) => { fields.filter((field2) => field2.type === "Lookup").forEach((lookupField) => { const queryRelatedDVFiles = lookupQueryResults.get(`${lookupField.fileClassName || "presetField"}___${lookupField.name}`) || []; const fileRelatedDVFiles = queryRelatedDVFiles.filter((dvFile) => { const targetValue = dvFile[lookupField.options.targetFieldName]; if (Array.isArray(targetValue)) { return targetValue.filter((v) => index.dv.api.value.isLink(v)).map((v) => v.path).includes(filePath); } else { return (targetValue == null ? void 0 : targetValue.path) === filePath; } }); const relatedFieldName = `${filePath}__related__${lookupField.fileClassName || "presetField"}___${lookupField.name}`; index.fileLookupFiles.set(relatedFieldName, fileRelatedDVFiles); }); }); for (let id of index.fileLookupFiles.keys()) { const matchRegex = /(?.*)__related__(?.*)___(?.*)/; const { filePath, fileClassName, fieldName } = ((_a = id.match(matchRegex)) == null ? void 0 : _a.groups) || {}; const existingLookFieldWithNameAndFileClassName = (_b = index.filesFields.get(filePath)) == null ? void 0 : _b.find( (field2) => field2.name === fieldName && (field2.fileClassName === void 0 && fileClassName === "presetField" || field2.fileClassName === fileClassName) ); const dvPage = index.dv.api.page(filePath); if (dvPage === void 0 || dvPage[fieldName] === void 0 || !existingLookFieldWithNameAndFileClassName) { index.fileLookupFiles.delete(id); index.fileLookupFieldLastValue.delete(id); index.fileLookupFieldLastOutputType.delete(id); index.fileLookupFieldsStatus.delete(`${filePath}__${fieldName}`); } } } // src/fields/models/Lookup.ts var Base20 = class { constructor() { this.type = "Lookup"; this.tagName = "lookup"; this.icon = "file-search"; this.tooltip = "Accepts a lookup query"; this.colorClass = "lookup"; } }; var DefaultOptions23 = { autoUpdate: false, dvQueryString: "", targetFieldName: "", outputType: "LinksList" /* LinksList */, builtinSummarizingFunction: Default.BuiltinSummarizing, customListFunction: Default.CustomList, customSummarizingFunction: Default.CustomSummarizing, summarizedFieldName: "" }; function settingsModal23(Base25) { return class InputSettingModal extends Base25 { constructor() { super(...arguments); this.createSettingContainer = () => { const container = this.optionsContainer; const autoUpdateTopContainer = container.createDiv({ cls: "vstacked" }); const autoUpdateContainer = autoUpdateTopContainer.createDiv({ cls: "field-container" }); autoUpdateContainer.createEl("span", { text: "Auto update this field ", cls: "label" }); autoUpdateContainer.createDiv({ cls: "spacer" }); const autoUpdate = new import_obsidian25.ToggleComponent(autoUpdateContainer); autoUpdateTopContainer.createEl("span", { text: "This could lead to latencies depending on the queries", cls: "sub-text warning" }); if (this.field.options.autoUpdate === void 0) this.field.options.autoUpdate = false; autoUpdate.setValue(this.field.options.autoUpdate); autoUpdate.onChange((value) => { this.field.options.autoUpdate = value; }); const dvQueryStringTopContainer = container.createDiv({ cls: "vstacked" }); dvQueryStringTopContainer.createEl("span", { text: "Pages to look for in your vault (DataviewJS Query)", cls: "label" }); dvQueryStringTopContainer.createEl("span", { text: "DataviewJS query of the form `dv.pages(...)`", cls: "sub-text" }); const dvQueryStringContainer = dvQueryStringTopContainer.createDiv({ cls: "field-container" }); const dvQueryString = new import_obsidian25.TextAreaComponent(dvQueryStringContainer); dvQueryString.inputEl.addClass("full-width"); dvQueryString.inputEl.cols = 50; dvQueryString.inputEl.rows = 4; dvQueryString.setValue(this.field.options.dvQueryString || ""); dvQueryString.setPlaceholder("exampe: dv.pages('#student')"); dvQueryString.onChange((value) => { this.field.options.dvQueryString = value; removeValidationError(dvQueryString); }); const targetFieldTopContainer = container.createDiv({ cls: "vstacked" }); const targetFieldContainer = targetFieldTopContainer.createDiv({ cls: "field-container" }); targetFieldContainer.createEl("span", { text: "Name of the related field", cls: "label" }); const targetFieldName = new import_obsidian25.TextComponent(targetFieldContainer); targetFieldName.inputEl.addClass("full-width"); targetFieldName.inputEl.addClass("with-label"); targetFieldTopContainer.createEl("span", { text: "field in the target pages that contains a link to the page where this lookup field is", cls: "sub-text" }); targetFieldName.setValue(this.field.options.targetFieldName || ""); targetFieldName.onChange((value) => { this.field.options.targetFieldName = value; removeValidationError(targetFieldName); }); const outputTypeContainer = container.createDiv({ cls: "field-container" }); this.field.options.outputType = this.field.options.outputType || "LinksList" /* LinksList */; outputTypeContainer.createEl("span", { text: "Type of output", cls: "label" }); outputTypeContainer.createDiv({ cls: "spacer" }); const outputTypeList = new import_obsidian25.DropdownComponent(outputTypeContainer); Object.keys(Type).forEach((outputType) => { outputTypeList.addOption(outputType, Description[outputType]); }); outputTypeList.setValue(this.field.options.outputType); const outputWarningContainer = container.createDiv(); outputWarningContainer.createEl("p", { text: "Warning: this may override some lines under your list. There shouldn't be an extra manual item in the list that is automatically rendered by this field: it would be overriden after each field indexing", cls: "field-warning" }); const builtinOptionsContainer = container.createDiv(); const builtinSummarizeFunctionTopContainer = builtinOptionsContainer.createDiv({ cls: "vstacked" }); const builtinSummarizeFunctionContainer = builtinSummarizeFunctionTopContainer.createDiv({ cls: "field-container" }); this.field.options.builtinSummarizingFunction = this.field.options.builtinSummarizingFunction || Default.BuiltinSummarizing; builtinSummarizeFunctionContainer.createEl("span", { text: OptionLabel.BuiltinSummarizing, cls: "label" }); builtinSummarizeFunctionContainer.createDiv({ cls: "spacer" }); const builtinSummarizeFunctionList = new import_obsidian25.DropdownComponent(builtinSummarizeFunctionContainer); Object.keys(BuiltinSummarizing).forEach((builtinFunction2) => { builtinSummarizeFunctionList.addOption(builtinFunction2, BuiltinSummarizing[builtinFunction2]); }); const builtinOptionsDescriptionContainer = builtinSummarizeFunctionTopContainer.createDiv({ cls: "sub-text" }); const builtinFunction = this.field.options.builtinSummarizingFunction; builtinOptionsDescriptionContainer.setText(BuiltinSummarizingFunctionDescription[builtinFunction].replace("{{summarizedFieldName}}", this.field.options.summarizedFieldName)); builtinSummarizeFunctionList.setValue(this.field.options.builtinSummarizingFunction); builtinSummarizeFunctionList.onChange((value) => { this.field.options.builtinSummarizingFunction = value; builtinOptionsDescriptionContainer.setText(BuiltinSummarizingFunctionDescription[value].replace("{{summarizedFieldName}}", this.field.options.summarizedFieldName)); }); const summarizedFieldNameTopContainer = builtinOptionsContainer.createDiv({ cls: "vstacked" }); this.field.options.summarizedFieldName = this.field.options.summarizedFieldName; const summarizedFieldNameContainer = summarizedFieldNameTopContainer.createDiv({ cls: "field-container" }); summarizedFieldNameContainer.createEl("span", { text: "Summarized field name", cls: "label" }); const summarizedFieldName = new import_obsidian25.TextComponent(summarizedFieldNameContainer); summarizedFieldName.inputEl.addClass("full-width"); summarizedFieldName.inputEl.addClass("with-label"); summarizedFieldNameTopContainer.createEl("span", { text: "Name of the field containing summarized value used for the summarizing function", cls: "sub-text" }); summarizedFieldName.setValue(this.field.options.summarizedFieldName); summarizedFieldName.onChange((value) => { this.field.options.summarizedFieldName = value; }); const outputRenderingFunctionTopContainer = container.createDiv({ cls: "vstacked" }); this.field.options.customListFunction = this.field.options.customListFunction || Default.CustomList; outputRenderingFunctionTopContainer.createEl("span", { text: OptionLabel.CustomList, cls: "label" }); outputRenderingFunctionTopContainer.createEl("code", { text: OptionSubLabel.CustomList }); const outputRenderingFunctionContainer = outputRenderingFunctionTopContainer.createDiv({ cls: "field-container" }); const outputRenderingFunction = new import_obsidian25.TextAreaComponent(outputRenderingFunctionContainer); outputRenderingFunction.inputEl.addClass("full-width"); outputRenderingFunction.setPlaceholder(Helper.CustomList); outputRenderingFunction.setValue(this.field.options.customListFunction); outputRenderingFunction.inputEl.cols = 65; outputRenderingFunction.inputEl.rows = 4; outputRenderingFunction.onChange((value) => { this.field.options.customListFunction = value; }); const outputSummarizingFunctionTopContainer = container.createDiv({ cls: "vstacked" }); this.field.options.customSummarizingFunction = this.field.options.customSummarizingFunction || Default.CustomSummarizing; outputSummarizingFunctionTopContainer.createEl("span", { text: OptionLabel.CustomSummarizing, cls: "label" }); outputSummarizingFunctionTopContainer.createEl("code", { text: OptionSubLabel.CustomSummarizing }); const outputSummarizingFunctionContainer = outputSummarizingFunctionTopContainer.createDiv({ cls: "field-container" }); const outputSummarizingFunction = new import_obsidian25.TextAreaComponent(outputSummarizingFunctionContainer); outputSummarizingFunction.inputEl.addClass("full-width"); outputSummarizingFunction.setPlaceholder(Helper.CustomSummarizing); outputSummarizingFunction.setValue(this.field.options.customSummarizingFunction); outputSummarizingFunction.inputEl.cols = 65; outputSummarizingFunction.inputEl.rows = 8; outputSummarizingFunction.onChange((value) => { this.field.options.customSummarizingFunction = value; }); const optionContainers = [ [["LinksList", "LinksBulletList"], void 0], [["BuiltinSummarizing"], builtinOptionsContainer], [["CustomList", "CustomBulletList"], outputRenderingFunctionTopContainer], [["CustomSummarizing"], outputSummarizingFunctionTopContainer] ]; this.displaySelectedOutputOptionContainer(optionContainers, outputTypeList.getValue()); this.displaySelectedOutputWarningContainer(outputWarningContainer, outputTypeList.getValue()); outputTypeList.onChange((value) => { this.field.options.outputType = value; this.displaySelectedOutputOptionContainer(optionContainers, value); this.displaySelectedOutputWarningContainer(outputWarningContainer, value); }); }; } displaySelectedOutputOptionContainer(optionContainers, value) { optionContainers.forEach((options_set) => { var _a, _b; if (options_set[0].includes(value)) { (_a = options_set[1]) == null ? void 0 : _a.show(); } else { (_b = options_set[1]) == null ? void 0 : _b.hide(); } }); } displaySelectedOutputWarningContainer(optionWarningContainer, value) { ["LinksBulletList" /* LinksBulletList */.toString(), "CustomBulletList" /* CustomBulletList */.toString()].includes(value) ? optionWarningContainer.show() : optionWarningContainer.hide(); } validateOptions() { return true; } }; } function valueString23(managedField) { if (isSingleTargeted(managedField)) return getLinksOrTextString(managedField.value, managedField.target); else return ""; } function displayValue23(managedField, container, onClicked = () => { }) { if (isSingleTargeted(managedField)) displayLinksOrText(managedField.value, managedField.target, container, managedField.plugin, () => onClicked); } function actions19(plugin, field2, file, location, indexedPath) { const name = field2.name; if (field2.options.autoUpdate === false || !plugin.settings.isAutoCalculationEnabled) { const f = plugin.fieldIndex; const id = `${file.path}__${field2.name}`; let status; status = f.fileLookupFieldsStatus.get(id) || "changed" /* changed */; if (f.fileLookupFieldLastOutputType.get(`${file.path}__related__${field2.fileClassName}___${field2.name}`) !== field2.options.outputType) status = "changed" /* changed */; const icon = statusIcon[status]; const action = async () => { if (!plugin.settings.isAutoCalculationEnabled) resolveLookups(plugin); await updateLookups(plugin, { file, fieldName: field2.name }); f.applyUpdates(); }; if (isSuggest(location) && ["changed" /* changed */, "mayHaveChanged" /* mayHaveChanged */].includes(status)) { location.options.push({ id: `update_${name}`, actionLabel: `Update ${name}`, action, icon }); } else if (isFieldActions(location) && ["changed" /* changed */, "mayHaveChanged" /* mayHaveChanged */].includes(status)) { location.addOption(`field_${field2.id}_update`, icon, action, `Update ${name}'s value`); } else if (isFieldActions(location) && status === "upToDate" /* upToDate */) { location.addOption(`field_${field2.id}_update`, icon, () => { }, `${name} is up to date`); } } else if (isFieldActions(location)) { location.addOption(`field_${field2.id}_update`, "server-cog", () => { }, `${name} is auto-updated`, "disabled"); } } function validateValue20(managedField) { return true; } function createDvField17(managedField, dv, p, fieldContainer, attrs = {}) { var _a, _b; attrs.cls = "value-container"; if (!isSingleTargeted(managedField)) return; const file = managedField.target; const fieldName = managedField.name; const fileClassName = ((_b = (_a = managedField.plugin.fieldIndex.filesFields.get(file.path)) == null ? void 0 : _a.find((f) => f.name === fieldName)) == null ? void 0 : _b.fileClassName) || "presetField"; const fieldValue = dv.el("span", managedField.plugin.fieldIndex.fileLookupFieldLastValue.get(`${file.path}__related__${fileClassName}___${fieldName}`), attrs); fieldContainer.appendChild(fieldValue); } function getOptionsStr18(field2) { const shortDescription = ShortDescription[field2.options.outputType]; let complement = ""; if (field2.options.outputType === "BuiltinSummarizing" /* BuiltinSummarizing */) { complement = ` ${field2.options.builtinSummarizingFunction}${field2.options.builtinSummarizingFunction !== "CountAll" /* CountAll */ ? " " + field2.options.summarizedFieldName : ""}`; } return shortDescription + complement; } // src/fields/models/abstractModels/AbstractRaw.ts var import_state2 = require("@codemirror/state"); // node_modules/codemirror/dist/index.js var import_view = require("@codemirror/view"); var import_view2 = require("@codemirror/view"); var import_state = require("@codemirror/state"); var import_language = require("@codemirror/language"); var import_commands = require("@codemirror/commands"); var import_search = require("@codemirror/search"); var import_autocomplete = require("@codemirror/autocomplete"); var import_lint = require("@codemirror/lint"); var basicSetup = /* @__PURE__ */ (() => [ (0, import_view.lineNumbers)(), (0, import_view.highlightActiveLineGutter)(), (0, import_view.highlightSpecialChars)(), (0, import_commands.history)(), (0, import_language.foldGutter)(), (0, import_view.drawSelection)(), (0, import_view.dropCursor)(), import_state.EditorState.allowMultipleSelections.of(true), (0, import_language.indentOnInput)(), (0, import_language.syntaxHighlighting)(import_language.defaultHighlightStyle, { fallback: true }), (0, import_language.bracketMatching)(), (0, import_autocomplete.closeBrackets)(), (0, import_autocomplete.autocompletion)(), (0, import_view.rectangularSelection)(), (0, import_view.crosshairCursor)(), (0, import_view.highlightActiveLine)(), (0, import_search.highlightSelectionMatches)(), import_view.keymap.of([ ...import_autocomplete.closeBracketsKeymap, ...import_commands.defaultKeymap, ...import_search.searchKeymap, ...import_commands.historyKeymap, ...import_language.foldKeymap, ...import_autocomplete.completionKeymap, ...import_lint.lintKeymap ]) ])(); // src/fields/models/abstractModels/AbstractRaw.ts var import_obsidian26 = require("obsidian"); var import_lint2 = require("@codemirror/lint"); var DefaultOptions24 = {}; function settingsModal24(Base25) { return class SettingsModal extends Base25 { createSettingContainer() { } validateOptions() { return true; } }; } function valueModal18(managedField, plugin) { const base = basicModal(managedField, plugin); return class ValueModal extends base { constructor(...rest) { super(); this.buildPositionContainer(); this.buildInputEl(this.contentEl.createDiv({ cls: "field-container" })); cleanActions(this.contentEl, ".footer-actions"); this.buildFooterBtn(); this.containerEl.addClass("metadata-menu"); } dumpValue(value) { return ""; } getExtraExtensions() { return []; } loadValue(value) { } buildPositionContainer() { this.positionContainer = this.contentEl.createDiv({ cls: "field-container" }); this.positionContainer.textContent = "Position: "; } buildInputEl(container) { const getPosition = (state) => { const range = state.selection.ranges.filter((range2) => range2.empty).first(); const position = (range == null ? void 0 : range.from) || 0; const line = state.doc.lineAt((range == null ? void 0 : range.head) || 0); const col = ((range == null ? void 0 : range.head) || 0) - line.from; this.positionContainer.textContent = `Line: ${line.number} | Col: ${col} | Position: ${position}`; }; const positionChange = import_state2.StateField.define({ create: (state) => getPosition(state), update(value, tr) { getPosition(tr.state); } }); const gutter = (0, import_lint2.lintGutter)(); this.editor = new import_view2.EditorView({ doc: this.dumpValue(this.loadValue(this.managedField.value)), extensions: [ basicSetup, gutter, positionChange, this.getExtraExtensions() ], parent: container }); } buildFooterBtn() { const buttonContainer = this.containerEl.createDiv({ cls: "footer-actions" }); buttonContainer.createDiv({ cls: "spacer" }); const infoContainer = buttonContainer.createDiv({ cls: "info" }); infoContainer.setText("Alt+Enter to save"); const confirmButton = new import_obsidian26.ButtonComponent(buttonContainer); confirmButton.setIcon("checkmark"); confirmButton.onClick(async () => { this.save(); this.close(); }); const cancelButton = new import_obsidian26.ButtonComponent(buttonContainer); cancelButton.setIcon("cross"); cancelButton.onClick(() => { this.close(); }); this.modalEl.appendChild(buttonContainer); } async save() { const newContent = this.editor.state.doc.toString().trim(); this.saved = true; this.managedField.save(newContent); this.close(); } }; } function actions20(plugin, field2, file, location, indexedPath) { const iconName = getIcon(field2.type); const action = async () => { var _a; const eF = await getExistingFieldForIndexedPath2(plugin, file, indexedPath); (_a = fieldValueManager(plugin, field2.id, field2.fileClassName, file, eF, indexedPath)) == null ? void 0 : _a.openModal(); }; if (isSuggest(location)) { location.options.push({ id: `update_${field2.name}`, actionLabel: `Update ${field2.name}`, action, icon: iconName }); } else if (isFieldActions(location)) { location.addOption(`field_${field2.id}_update`, iconName, action, `Update ${field2.name}'s value`); } } // node_modules/@lezer/json/dist/index.js var import_lr = require("@lezer/lr"); var import_highlight = require("@lezer/highlight"); var jsonHighlighting = (0, import_highlight.styleTags)({ String: import_highlight.tags.string, Number: import_highlight.tags.number, "True False": import_highlight.tags.bool, PropertyName: import_highlight.tags.propertyName, Null: import_highlight.tags.null, ",": import_highlight.tags.separator, "[ ]": import_highlight.tags.squareBracket, "{ }": import_highlight.tags.brace }); var parser = import_lr.LRParser.deserialize({ version: 14, states: "$bOVQPOOOOQO'#Cb'#CbOnQPO'#CeOvQPO'#CjOOQO'#Cp'#CpQOQPOOOOQO'#Cg'#CgO}QPO'#CfO!SQPO'#CrOOQO,59P,59PO![QPO,59PO!aQPO'#CuOOQO,59U,59UO!iQPO,59UOVQPO,59QOqQPO'#CkO!nQPO,59^OOQO1G.k1G.kOVQPO'#ClO!vQPO,59aOOQO1G.p1G.pOOQO1G.l1G.lOOQO,59V,59VOOQO-E6i-E6iOOQO,59W,59WOOQO-E6j-E6j", stateData: "#O~OcOS~OQSORSOSSOTSOWQO]ROePO~OVXOeUO~O[[O~PVOg^O~Oh_OVfX~OVaO~OhbO[iX~O[dO~Oh_OVfa~OhbO[ia~O", goto: "!kjPPPPPPkPPkqwPPk{!RPPP!XP!ePP!hXSOR^bQWQRf_TVQ_Q`WRg`QcZRicQTOQZRQe^RhbRYQR]R", nodeNames: "\u26A0 JsonText True False Null Number String } { Object Property PropertyName ] [ Array", maxTerm: 25, nodeProps: [ ["openedBy", 7, "{", 12, "["], ["closedBy", 8, "}", 13, "]"] ], propSources: [jsonHighlighting], skippedNodes: [0], repeatNodeCount: 2, tokenData: "(|~RaXY!WYZ!W]^!Wpq!Wrs!]|}$u}!O$z!Q!R%T!R![&c![!]&t!}#O&y#P#Q'O#Y#Z'T#b#c'r#h#i(Z#o#p(r#q#r(w~!]Oc~~!`Wpq!]qr!]rs!xs#O!]#O#P!}#P;'S!];'S;=`$o<%lO!]~!}Oe~~#QXrs!]!P!Q!]#O#P!]#U#V!]#Y#Z!]#b#c!]#f#g!]#h#i!]#i#j#m~#pR!Q![#y!c!i#y#T#Z#y~#|R!Q![$V!c!i$V#T#Z$V~$YR!Q![$c!c!i$c#T#Z$c~$fR!Q![!]!c!i!]#T#Z!]~$rP;=`<%l!]~$zOh~~$}Q!Q!R%T!R![&c~%YRT~!O!P%c!g!h%w#X#Y%w~%fP!Q![%i~%nRT~!Q![%i!g!h%w#X#Y%w~%zR{|&T}!O&T!Q![&Z~&WP!Q![&Z~&`PT~!Q![&Z~&hST~!O!P%c!Q![&c!g!h%w#X#Y%w~&yOg~~'OO]~~'TO[~~'WP#T#U'Z~'^P#`#a'a~'dP#g#h'g~'jP#X#Y'm~'rOR~~'uP#i#j'x~'{P#`#a(O~(RP#`#a(U~(ZOS~~(^P#f#g(a~(dP#i#j(g~(jP#X#Y(m~(rOQ~~(wOW~~(|OV~", tokenizers: [0], topRules: { "JsonText": [0, 1] }, tokenPrec: 0 }); // node_modules/@codemirror/lang-json/dist/index.js var import_language2 = require("@codemirror/language"); var jsonLanguage = /* @__PURE__ */ import_language2.LRLanguage.define({ name: "json", parser: /* @__PURE__ */ parser.configure({ props: [ /* @__PURE__ */ import_language2.indentNodeProp.add({ Object: /* @__PURE__ */ (0, import_language2.continuedIndent)({ except: /^\s*\}/ }), Array: /* @__PURE__ */ (0, import_language2.continuedIndent)({ except: /^\s*\]/ }) }), /* @__PURE__ */ import_language2.foldNodeProp.add({ "Object Array": import_language2.foldInside }) ] }), languageData: { closeBrackets: { brackets: ["[", "{", '"'] }, indentOnInput: /^\s*[\}\]]$/ } }); function json() { return new import_language2.LanguageSupport(jsonLanguage); } // src/fields/models/JSON.ts var import_lint3 = require("@codemirror/lint"); var import_obsidian27 = require("obsidian"); var Base21 = class { constructor() { this.type = "JSON"; this.tagName = "json"; this.icon = "file-json-2"; this.tooltip = "Accepts a JSON object"; this.colorClass = "file"; } }; var DefaultOptions25 = DefaultOptions24; function settingsModal25(Base25) { return settingsModal24(Base25); } function valueModal19(managedField, plugin) { const base = valueModal18(managedField, plugin); return class ValueModal extends base { dumpValue(value) { return `${JSON.stringify(value, null, " ") || ""}`; } getExtraExtensions() { const jsonLinter = (0, import_lint3.linter)((view) => { let diagnostics = []; try { JSON.parse(view.state.doc.toString()); } catch (e) { var loc = e.mark; var from = loc ? Math.min(loc.position, view.state.doc.length) : 0; var to = from; var severity = "error"; diagnostics.push({ from, to, message: e.message, severity }); } return diagnostics; }); return [json(), jsonLinter]; } loadValue(value) { try { return JSON.parse(value || "{}"); } catch (e) { return value; } } }; } function valueString24(managedField) { const valueString29 = `${JSON.stringify(managedField.value, null, " ") || ""}`; return `${valueString29.slice(0, 50)}${valueString29.length > 50 ? "..." : ""}`; } function displayValue24(managedField, container, onClicked) { container.setText(valueString24(managedField)); } function createDvField18(managedField, dv, p, fieldContainer, attrs = {}) { var _a, _b; attrs.cls = "value-container"; const fieldValue = dv.el("span", managedField.value || "", attrs); fieldContainer.appendChild(fieldValue); const editBtn = fieldContainer.createEl("button"); const spacer = fieldContainer.createDiv({ cls: "spacer-1" }); if ((_a = attrs.options) == null ? void 0 : _a.alwaysOn) spacer.hide(); (0, import_obsidian27.setIcon)(editBtn, getIcon(managedField.type)); if (!((_b = attrs == null ? void 0 : attrs.options) == null ? void 0 : _b.alwaysOn)) { editBtn.hide(); spacer.show(); fieldContainer.onmouseover = () => { editBtn.show(); spacer.hide(); }; fieldContainer.onmouseout = () => { var _a2; editBtn.hide(); if (!((_a2 = attrs.options) == null ? void 0 : _a2.alwaysOn)) spacer.show(); }; } editBtn.onclick = async () => { managedField.openModal(); fieldValue.hide(); editBtn.hide(); spacer.hide(); }; } function actions21(plugin, field2, file, location, indexedPath) { return actions20(plugin, field2, file, location, indexedPath); } function validateValue21(managedField) { try { JSON.parse(managedField.value); return true; } catch (e) { return false; } } // src/fields/models/YAML.ts var import_language3 = require("@codemirror/language"); // node_modules/@codemirror/legacy-modes/mode/yaml.js var cons = ["true", "false", "on", "off", "yes", "no"]; var keywordRegex = new RegExp("\\b((" + cons.join(")|(") + "))$", "i"); var yaml = { name: "yaml", token: function(stream, state) { var ch = stream.peek(); var esc = state.escaped; state.escaped = false; if (ch == "#" && (stream.pos == 0 || /\s/.test(stream.string.charAt(stream.pos - 1)))) { stream.skipToEnd(); return "comment"; } if (stream.match(/^('([^']|\\.)*'?|"([^"]|\\.)*"?)/)) return "string"; if (state.literal && stream.indentation() > state.keyCol) { stream.skipToEnd(); return "string"; } else if (state.literal) { state.literal = false; } if (stream.sol()) { state.keyCol = 0; state.pair = false; state.pairStart = false; if (stream.match("---")) { return "def"; } if (stream.match("...")) { return "def"; } if (stream.match(/^\s*-\s+/)) { return "meta"; } } if (stream.match(/^(\{|\}|\[|\])/)) { if (ch == "{") state.inlinePairs++; else if (ch == "}") state.inlinePairs--; else if (ch == "[") state.inlineList++; else state.inlineList--; return "meta"; } if (state.inlineList > 0 && !esc && ch == ",") { stream.next(); return "meta"; } if (state.inlinePairs > 0 && !esc && ch == ",") { state.keyCol = 0; state.pair = false; state.pairStart = false; stream.next(); return "meta"; } if (state.pairStart) { if (stream.match(/^\s*(\||\>)\s*/)) { state.literal = true; return "meta"; } ; if (stream.match(/^\s*(\&|\*)[a-z0-9\._-]+\b/i)) { return "variable"; } if (state.inlinePairs == 0 && stream.match(/^\s*-?[0-9\.\,]+\s?$/)) { return "number"; } if (state.inlinePairs > 0 && stream.match(/^\s*-?[0-9\.\,]+\s?(?=(,|}))/)) { return "number"; } if (stream.match(keywordRegex)) { return "keyword"; } } if (!state.pair && stream.match(/^\s*(?:[,\[\]{}&*!|>'"%@`][^\s'":]|[^,\[\]{}#&*!|>'"%@`])[^#]*?(?=\s*:($|\s))/)) { state.pair = true; state.keyCol = stream.indentation(); return "atom"; } if (state.pair && stream.match(/^:\s*/)) { state.pairStart = true; return "meta"; } state.pairStart = false; state.escaped = ch == "\\"; stream.next(); return null; }, startState: function() { return { pair: false, pairStart: false, keyCol: 0, inlinePairs: 0, inlineList: 0, literal: false, escaped: false }; }, languageData: { commentTokens: { line: "#" } } }; // src/fields/models/YAML.ts var import_lint4 = require("@codemirror/lint"); // node_modules/yaml/browser/dist/nodes/identity.js var ALIAS = Symbol.for("yaml.alias"); var DOC = Symbol.for("yaml.document"); var MAP = Symbol.for("yaml.map"); var PAIR = Symbol.for("yaml.pair"); var SCALAR = Symbol.for("yaml.scalar"); var SEQ = Symbol.for("yaml.seq"); var NODE_TYPE = Symbol.for("yaml.node.type"); var isAlias = (node) => !!node && typeof node === "object" && node[NODE_TYPE] === ALIAS; var isDocument = (node) => !!node && typeof node === "object" && node[NODE_TYPE] === DOC; var isMap = (node) => !!node && typeof node === "object" && node[NODE_TYPE] === MAP; var isPair = (node) => !!node && typeof node === "object" && node[NODE_TYPE] === PAIR; var isScalar = (node) => !!node && typeof node === "object" && node[NODE_TYPE] === SCALAR; var isSeq = (node) => !!node && typeof node === "object" && node[NODE_TYPE] === SEQ; function isCollection(node) { if (node && typeof node === "object") switch (node[NODE_TYPE]) { case MAP: case SEQ: return true; } return false; } function isNode(node) { if (node && typeof node === "object") switch (node[NODE_TYPE]) { case ALIAS: case MAP: case SCALAR: case SEQ: return true; } return false; } var hasAnchor = (node) => (isScalar(node) || isCollection(node)) && !!node.anchor; // node_modules/yaml/browser/dist/visit.js var BREAK = Symbol("break visit"); var SKIP = Symbol("skip children"); var REMOVE = Symbol("remove node"); function visit(node, visitor) { const visitor_ = initVisitor(visitor); if (isDocument(node)) { const cd = visit_(null, node.contents, visitor_, Object.freeze([node])); if (cd === REMOVE) node.contents = null; } else visit_(null, node, visitor_, Object.freeze([])); } visit.BREAK = BREAK; visit.SKIP = SKIP; visit.REMOVE = REMOVE; function visit_(key, node, visitor, path) { const ctrl = callVisitor(key, node, visitor, path); if (isNode(ctrl) || isPair(ctrl)) { replaceNode(key, path, ctrl); return visit_(key, ctrl, visitor, path); } if (typeof ctrl !== "symbol") { if (isCollection(node)) { path = Object.freeze(path.concat(node)); for (let i = 0; i < node.items.length; ++i) { const ci = visit_(i, node.items[i], visitor, path); if (typeof ci === "number") i = ci - 1; else if (ci === BREAK) return BREAK; else if (ci === REMOVE) { node.items.splice(i, 1); i -= 1; } } } else if (isPair(node)) { path = Object.freeze(path.concat(node)); const ck = visit_("key", node.key, visitor, path); if (ck === BREAK) return BREAK; else if (ck === REMOVE) node.key = null; const cv = visit_("value", node.value, visitor, path); if (cv === BREAK) return BREAK; else if (cv === REMOVE) node.value = null; } } return ctrl; } async function visitAsync(node, visitor) { const visitor_ = initVisitor(visitor); if (isDocument(node)) { const cd = await visitAsync_(null, node.contents, visitor_, Object.freeze([node])); if (cd === REMOVE) node.contents = null; } else await visitAsync_(null, node, visitor_, Object.freeze([])); } visitAsync.BREAK = BREAK; visitAsync.SKIP = SKIP; visitAsync.REMOVE = REMOVE; async function visitAsync_(key, node, visitor, path) { const ctrl = await callVisitor(key, node, visitor, path); if (isNode(ctrl) || isPair(ctrl)) { replaceNode(key, path, ctrl); return visitAsync_(key, ctrl, visitor, path); } if (typeof ctrl !== "symbol") { if (isCollection(node)) { path = Object.freeze(path.concat(node)); for (let i = 0; i < node.items.length; ++i) { const ci = await visitAsync_(i, node.items[i], visitor, path); if (typeof ci === "number") i = ci - 1; else if (ci === BREAK) return BREAK; else if (ci === REMOVE) { node.items.splice(i, 1); i -= 1; } } } else if (isPair(node)) { path = Object.freeze(path.concat(node)); const ck = await visitAsync_("key", node.key, visitor, path); if (ck === BREAK) return BREAK; else if (ck === REMOVE) node.key = null; const cv = await visitAsync_("value", node.value, visitor, path); if (cv === BREAK) return BREAK; else if (cv === REMOVE) node.value = null; } } return ctrl; } function initVisitor(visitor) { if (typeof visitor === "object" && (visitor.Collection || visitor.Node || visitor.Value)) { return Object.assign({ Alias: visitor.Node, Map: visitor.Node, Scalar: visitor.Node, Seq: visitor.Node }, visitor.Value && { Map: visitor.Value, Scalar: visitor.Value, Seq: visitor.Value }, visitor.Collection && { Map: visitor.Collection, Seq: visitor.Collection }, visitor); } return visitor; } function callVisitor(key, node, visitor, path) { var _a, _b, _c, _d, _e; if (typeof visitor === "function") return visitor(key, node, path); if (isMap(node)) return (_a = visitor.Map) == null ? void 0 : _a.call(visitor, key, node, path); if (isSeq(node)) return (_b = visitor.Seq) == null ? void 0 : _b.call(visitor, key, node, path); if (isPair(node)) return (_c = visitor.Pair) == null ? void 0 : _c.call(visitor, key, node, path); if (isScalar(node)) return (_d = visitor.Scalar) == null ? void 0 : _d.call(visitor, key, node, path); if (isAlias(node)) return (_e = visitor.Alias) == null ? void 0 : _e.call(visitor, key, node, path); return void 0; } function replaceNode(key, path, node) { const parent = path[path.length - 1]; if (isCollection(parent)) { parent.items[key] = node; } else if (isPair(parent)) { if (key === "key") parent.key = node; else parent.value = node; } else if (isDocument(parent)) { parent.contents = node; } else { const pt = isAlias(parent) ? "alias" : "scalar"; throw new Error(`Cannot replace node with ${pt} parent`); } } // node_modules/yaml/browser/dist/doc/directives.js var escapeChars = { "!": "%21", ",": "%2C", "[": "%5B", "]": "%5D", "{": "%7B", "}": "%7D" }; var escapeTagName = (tn) => tn.replace(/[!,[\]{}]/g, (ch) => escapeChars[ch]); var Directives = class { constructor(yaml2, tags2) { this.docStart = null; this.docEnd = false; this.yaml = Object.assign({}, Directives.defaultYaml, yaml2); this.tags = Object.assign({}, Directives.defaultTags, tags2); } clone() { const copy = new Directives(this.yaml, this.tags); copy.docStart = this.docStart; return copy; } /** * During parsing, get a Directives instance for the current document and * update the stream state according to the current version's spec. */ atDocument() { const res = new Directives(this.yaml, this.tags); switch (this.yaml.version) { case "1.1": this.atNextDocument = true; break; case "1.2": this.atNextDocument = false; this.yaml = { explicit: Directives.defaultYaml.explicit, version: "1.2" }; this.tags = Object.assign({}, Directives.defaultTags); break; } return res; } /** * @param onError - May be called even if the action was successful * @returns `true` on success */ add(line, onError) { if (this.atNextDocument) { this.yaml = { explicit: Directives.defaultYaml.explicit, version: "1.1" }; this.tags = Object.assign({}, Directives.defaultTags); this.atNextDocument = false; } const parts = line.trim().split(/[ \t]+/); const name = parts.shift(); switch (name) { case "%TAG": { if (parts.length !== 2) { onError(0, "%TAG directive should contain exactly two parts"); if (parts.length < 2) return false; } const [handle, prefix] = parts; this.tags[handle] = prefix; return true; } case "%YAML": { this.yaml.explicit = true; if (parts.length !== 1) { onError(0, "%YAML directive should contain exactly one part"); return false; } const [version] = parts; if (version === "1.1" || version === "1.2") { this.yaml.version = version; return true; } else { const isValid = /^\d+\.\d+$/.test(version); onError(6, `Unsupported YAML version ${version}`, isValid); return false; } } default: onError(0, `Unknown directive ${name}`, true); return false; } } /** * Resolves a tag, matching handles to those defined in %TAG directives. * * @returns Resolved tag, which may also be the non-specific tag `'!'` or a * `'!local'` tag, or `null` if unresolvable. */ tagName(source, onError) { if (source === "!") return "!"; if (source[0] !== "!") { onError(`Not a valid tag: ${source}`); return null; } if (source[1] === "<") { const verbatim = source.slice(2, -1); if (verbatim === "!" || verbatim === "!!") { onError(`Verbatim tags aren't resolved, so ${source} is invalid.`); return null; } if (source[source.length - 1] !== ">") onError("Verbatim tags must end with a >"); return verbatim; } const [, handle, suffix] = source.match(/^(.*!)([^!]*)$/); if (!suffix) onError(`The ${source} tag has no suffix`); const prefix = this.tags[handle]; if (prefix) { try { return prefix + decodeURIComponent(suffix); } catch (error) { onError(String(error)); return null; } } if (handle === "!") return source; onError(`Could not resolve tag: ${source}`); return null; } /** * Given a fully resolved tag, returns its printable string form, * taking into account current tag prefixes and defaults. */ tagString(tag) { for (const [handle, prefix] of Object.entries(this.tags)) { if (tag.startsWith(prefix)) return handle + escapeTagName(tag.substring(prefix.length)); } return tag[0] === "!" ? tag : `!<${tag}>`; } toString(doc) { const lines = this.yaml.explicit ? [`%YAML ${this.yaml.version || "1.2"}`] : []; const tagEntries = Object.entries(this.tags); let tagNames; if (doc && tagEntries.length > 0 && isNode(doc.contents)) { const tags2 = {}; visit(doc.contents, (_key, node) => { if (isNode(node) && node.tag) tags2[node.tag] = true; }); tagNames = Object.keys(tags2); } else tagNames = []; for (const [handle, prefix] of tagEntries) { if (handle === "!!" && prefix === "tag:yaml.org,2002:") continue; if (!doc || tagNames.some((tn) => tn.startsWith(prefix))) lines.push(`%TAG ${handle} ${prefix}`); } return lines.join("\n"); } }; Directives.defaultYaml = { explicit: false, version: "1.2" }; Directives.defaultTags = { "!!": "tag:yaml.org,2002:" }; // node_modules/yaml/browser/dist/doc/anchors.js function anchorIsValid(anchor) { if (/[\x00-\x19\s,[\]{}]/.test(anchor)) { const sa = JSON.stringify(anchor); const msg = `Anchor must not contain whitespace or control characters: ${sa}`; throw new Error(msg); } return true; } function anchorNames(root) { const anchors = /* @__PURE__ */ new Set(); visit(root, { Value(_key, node) { if (node.anchor) anchors.add(node.anchor); } }); return anchors; } function findNewAnchor(prefix, exclude) { for (let i = 1; true; ++i) { const name = `${prefix}${i}`; if (!exclude.has(name)) return name; } } function createNodeAnchors(doc, prefix) { const aliasObjects = []; const sourceObjects = /* @__PURE__ */ new Map(); let prevAnchors = null; return { onAnchor: (source) => { aliasObjects.push(source); if (!prevAnchors) prevAnchors = anchorNames(doc); const anchor = findNewAnchor(prefix, prevAnchors); prevAnchors.add(anchor); return anchor; }, /** * With circular references, the source node is only resolved after all * of its child nodes are. This is why anchors are set only after all of * the nodes have been created. */ setAnchors: () => { for (const source of aliasObjects) { const ref = sourceObjects.get(source); if (typeof ref === "object" && ref.anchor && (isScalar(ref.node) || isCollection(ref.node))) { ref.node.anchor = ref.anchor; } else { const error = new Error("Failed to resolve repeated object (this should not happen)"); error.source = source; throw error; } } }, sourceObjects }; } // node_modules/yaml/browser/dist/doc/applyReviver.js function applyReviver(reviver, obj, key, val) { if (val && typeof val === "object") { if (Array.isArray(val)) { for (let i = 0, len = val.length; i < len; ++i) { const v0 = val[i]; const v1 = applyReviver(reviver, val, String(i), v0); if (v1 === void 0) delete val[i]; else if (v1 !== v0) val[i] = v1; } } else if (val instanceof Map) { for (const k of Array.from(val.keys())) { const v0 = val.get(k); const v1 = applyReviver(reviver, val, k, v0); if (v1 === void 0) val.delete(k); else if (v1 !== v0) val.set(k, v1); } } else if (val instanceof Set) { for (const v0 of Array.from(val)) { const v1 = applyReviver(reviver, val, v0, v0); if (v1 === void 0) val.delete(v0); else if (v1 !== v0) { val.delete(v0); val.add(v1); } } } else { for (const [k, v0] of Object.entries(val)) { const v1 = applyReviver(reviver, val, k, v0); if (v1 === void 0) delete val[k]; else if (v1 !== v0) val[k] = v1; } } } return reviver.call(obj, key, val); } // node_modules/yaml/browser/dist/nodes/toJS.js function toJS(value, arg, ctx) { if (Array.isArray(value)) return value.map((v, i) => toJS(v, String(i), ctx)); if (value && typeof value.toJSON === "function") { if (!ctx || !hasAnchor(value)) return value.toJSON(arg, ctx); const data = { aliasCount: 0, count: 1, res: void 0 }; ctx.anchors.set(value, data); ctx.onCreate = (res2) => { data.res = res2; delete ctx.onCreate; }; const res = value.toJSON(arg, ctx); if (ctx.onCreate) ctx.onCreate(res); return res; } if (typeof value === "bigint" && !(ctx == null ? void 0 : ctx.keep)) return Number(value); return value; } // node_modules/yaml/browser/dist/nodes/Node.js var NodeBase = class { constructor(type) { Object.defineProperty(this, NODE_TYPE, { value: type }); } /** Create a copy of this node. */ clone() { const copy = Object.create(Object.getPrototypeOf(this), Object.getOwnPropertyDescriptors(this)); if (this.range) copy.range = this.range.slice(); return copy; } /** A plain JavaScript representation of this node. */ toJS(doc, { mapAsMap, maxAliasCount, onAnchor, reviver } = {}) { if (!isDocument(doc)) throw new TypeError("A document argument is required"); const ctx = { anchors: /* @__PURE__ */ new Map(), doc, keep: true, mapAsMap: mapAsMap === true, mapKeyWarned: false, maxAliasCount: typeof maxAliasCount === "number" ? maxAliasCount : 100 }; const res = toJS(this, "", ctx); if (typeof onAnchor === "function") for (const { count, res: res2 } of ctx.anchors.values()) onAnchor(res2, count); return typeof reviver === "function" ? applyReviver(reviver, { "": res }, "", res) : res; } }; // node_modules/yaml/browser/dist/nodes/Alias.js var Alias = class extends NodeBase { constructor(source) { super(ALIAS); this.source = source; Object.defineProperty(this, "tag", { set() { throw new Error("Alias nodes cannot have tags"); } }); } /** * Resolve the value of this alias within `doc`, finding the last * instance of the `source` anchor before this node. */ resolve(doc) { let found = void 0; visit(doc, { Node: (_key, node) => { if (node === this) return visit.BREAK; if (node.anchor === this.source) found = node; } }); return found; } toJSON(_arg, ctx) { if (!ctx) return { source: this.source }; const { anchors, doc, maxAliasCount } = ctx; const source = this.resolve(doc); if (!source) { const msg = `Unresolved alias (the anchor must be set before the alias): ${this.source}`; throw new ReferenceError(msg); } let data = anchors.get(source); if (!data) { toJS(source, null, ctx); data = anchors.get(source); } if (!data || data.res === void 0) { const msg = "This should not happen: Alias anchor was not resolved?"; throw new ReferenceError(msg); } if (maxAliasCount >= 0) { data.count += 1; if (data.aliasCount === 0) data.aliasCount = getAliasCount(doc, source, anchors); if (data.count * data.aliasCount > maxAliasCount) { const msg = "Excessive alias count indicates a resource exhaustion attack"; throw new ReferenceError(msg); } } return data.res; } toString(ctx, _onComment, _onChompKeep) { const src = `*${this.source}`; if (ctx) { anchorIsValid(this.source); if (ctx.options.verifyAliasOrder && !ctx.anchors.has(this.source)) { const msg = `Unresolved alias (the anchor must be set before the alias): ${this.source}`; throw new Error(msg); } if (ctx.implicitKey) return `${src} `; } return src; } }; function getAliasCount(doc, node, anchors) { if (isAlias(node)) { const source = node.resolve(doc); const anchor = anchors && source && anchors.get(source); return anchor ? anchor.count * anchor.aliasCount : 0; } else if (isCollection(node)) { let count = 0; for (const item of node.items) { const c = getAliasCount(doc, item, anchors); if (c > count) count = c; } return count; } else if (isPair(node)) { const kc = getAliasCount(doc, node.key, anchors); const vc = getAliasCount(doc, node.value, anchors); return Math.max(kc, vc); } return 1; } // node_modules/yaml/browser/dist/nodes/Scalar.js var isScalarValue = (value) => !value || typeof value !== "function" && typeof value !== "object"; var Scalar = class extends NodeBase { constructor(value) { super(SCALAR); this.value = value; } toJSON(arg, ctx) { return (ctx == null ? void 0 : ctx.keep) ? this.value : toJS(this.value, arg, ctx); } toString() { return String(this.value); } }; Scalar.BLOCK_FOLDED = "BLOCK_FOLDED"; Scalar.BLOCK_LITERAL = "BLOCK_LITERAL"; Scalar.PLAIN = "PLAIN"; Scalar.QUOTE_DOUBLE = "QUOTE_DOUBLE"; Scalar.QUOTE_SINGLE = "QUOTE_SINGLE"; // node_modules/yaml/browser/dist/doc/createNode.js var defaultTagPrefix = "tag:yaml.org,2002:"; function findTagObject(value, tagName, tags2) { var _a; if (tagName) { const match = tags2.filter((t) => t.tag === tagName); const tagObj = (_a = match.find((t) => !t.format)) != null ? _a : match[0]; if (!tagObj) throw new Error(`Tag ${tagName} not found`); return tagObj; } return tags2.find((t) => { var _a2; return ((_a2 = t.identify) == null ? void 0 : _a2.call(t, value)) && !t.format; }); } function createNode(value, tagName, ctx) { var _a, _b, _c; if (isDocument(value)) value = value.contents; if (isNode(value)) return value; if (isPair(value)) { const map2 = (_b = (_a = ctx.schema[MAP]).createNode) == null ? void 0 : _b.call(_a, ctx.schema, null, ctx); map2.items.push(value); return map2; } if (value instanceof String || value instanceof Number || value instanceof Boolean || typeof BigInt !== "undefined" && value instanceof BigInt) { value = value.valueOf(); } const { aliasDuplicateObjects, onAnchor, onTagObj, schema: schema4, sourceObjects } = ctx; let ref = void 0; if (aliasDuplicateObjects && value && typeof value === "object") { ref = sourceObjects.get(value); if (ref) { if (!ref.anchor) ref.anchor = onAnchor(value); return new Alias(ref.anchor); } else { ref = { anchor: null, node: null }; sourceObjects.set(value, ref); } } if (tagName == null ? void 0 : tagName.startsWith("!!")) tagName = defaultTagPrefix + tagName.slice(2); let tagObj = findTagObject(value, tagName, schema4.tags); if (!tagObj) { if (value && typeof value.toJSON === "function") { value = value.toJSON(); } if (!value || typeof value !== "object") { const node2 = new Scalar(value); if (ref) ref.node = node2; return node2; } tagObj = value instanceof Map ? schema4[MAP] : Symbol.iterator in Object(value) ? schema4[SEQ] : schema4[MAP]; } if (onTagObj) { onTagObj(tagObj); delete ctx.onTagObj; } const node = (tagObj == null ? void 0 : tagObj.createNode) ? tagObj.createNode(ctx.schema, value, ctx) : typeof ((_c = tagObj == null ? void 0 : tagObj.nodeClass) == null ? void 0 : _c.from) === "function" ? tagObj.nodeClass.from(ctx.schema, value, ctx) : new Scalar(value); if (tagName) node.tag = tagName; else if (!tagObj.default) node.tag = tagObj.tag; if (ref) ref.node = node; return node; } // node_modules/yaml/browser/dist/nodes/Collection.js function collectionFromPath(schema4, path, value) { let v = value; for (let i = path.length - 1; i >= 0; --i) { const k = path[i]; if (typeof k === "number" && Number.isInteger(k) && k >= 0) { const a = []; a[k] = v; v = a; } else { v = /* @__PURE__ */ new Map([[k, v]]); } } return createNode(v, void 0, { aliasDuplicateObjects: false, keepUndefined: false, onAnchor: () => { throw new Error("This should not happen, please report a bug."); }, schema: schema4, sourceObjects: /* @__PURE__ */ new Map() }); } var isEmptyPath = (path) => path == null || typeof path === "object" && !!path[Symbol.iterator]().next().done; var Collection = class extends NodeBase { constructor(type, schema4) { super(type); Object.defineProperty(this, "schema", { value: schema4, configurable: true, enumerable: false, writable: true }); } /** * Create a copy of this collection. * * @param schema - If defined, overwrites the original's schema */ clone(schema4) { const copy = Object.create(Object.getPrototypeOf(this), Object.getOwnPropertyDescriptors(this)); if (schema4) copy.schema = schema4; copy.items = copy.items.map((it) => isNode(it) || isPair(it) ? it.clone(schema4) : it); if (this.range) copy.range = this.range.slice(); return copy; } /** * Adds a value to the collection. For `!!map` and `!!omap` the value must * be a Pair instance or a `{ key, value }` object, which may not have a key * that already exists in the map. */ addIn(path, value) { if (isEmptyPath(path)) this.add(value); else { const [key, ...rest] = path; const node = this.get(key, true); if (isCollection(node)) node.addIn(rest, value); else if (node === void 0 && this.schema) this.set(key, collectionFromPath(this.schema, rest, value)); else throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`); } } /** * Removes a value from the collection. * @returns `true` if the item was found and removed. */ deleteIn(path) { const [key, ...rest] = path; if (rest.length === 0) return this.delete(key); const node = this.get(key, true); if (isCollection(node)) return node.deleteIn(rest); else throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`); } /** * Returns item at `key`, or `undefined` if not found. By default unwraps * scalar values from their surrounding node; to disable set `keepScalar` to * `true` (collections are always returned intact). */ getIn(path, keepScalar) { const [key, ...rest] = path; const node = this.get(key, true); if (rest.length === 0) return !keepScalar && isScalar(node) ? node.value : node; else return isCollection(node) ? node.getIn(rest, keepScalar) : void 0; } hasAllNullValues(allowScalar) { return this.items.every((node) => { if (!isPair(node)) return false; const n = node.value; return n == null || allowScalar && isScalar(n) && n.value == null && !n.commentBefore && !n.comment && !n.tag; }); } /** * Checks if the collection includes a value with the key `key`. */ hasIn(path) { const [key, ...rest] = path; if (rest.length === 0) return this.has(key); const node = this.get(key, true); return isCollection(node) ? node.hasIn(rest) : false; } /** * Sets a value in this collection. For `!!set`, `value` needs to be a * boolean to add/remove the item from the set. */ setIn(path, value) { const [key, ...rest] = path; if (rest.length === 0) { this.set(key, value); } else { const node = this.get(key, true); if (isCollection(node)) node.setIn(rest, value); else if (node === void 0 && this.schema) this.set(key, collectionFromPath(this.schema, rest, value)); else throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`); } } }; Collection.maxFlowStringSingleLineLength = 60; // node_modules/yaml/browser/dist/stringify/stringifyComment.js var stringifyComment = (str) => str.replace(/^(?!$)(?: $)?/gm, "#"); function indentComment(comment, indent) { if (/^\n+$/.test(comment)) return comment.substring(1); return indent ? comment.replace(/^(?! *$)/gm, indent) : comment; } var lineComment = (str, indent, comment) => str.endsWith("\n") ? indentComment(comment, indent) : comment.includes("\n") ? "\n" + indentComment(comment, indent) : (str.endsWith(" ") ? "" : " ") + comment; // node_modules/yaml/browser/dist/stringify/foldFlowLines.js var FOLD_FLOW = "flow"; var FOLD_BLOCK = "block"; var FOLD_QUOTED = "quoted"; function foldFlowLines(text, indent, mode = "flow", { indentAtStart, lineWidth = 80, minContentWidth = 20, onFold, onOverflow } = {}) { if (!lineWidth || lineWidth < 0) return text; const endStep = Math.max(1 + minContentWidth, 1 + lineWidth - indent.length); if (text.length <= endStep) return text; const folds = []; const escapedFolds = {}; let end2 = lineWidth - indent.length; if (typeof indentAtStart === "number") { if (indentAtStart > lineWidth - Math.max(2, minContentWidth)) folds.push(0); else end2 = lineWidth - indentAtStart; } let split = void 0; let prev = void 0; let overflow = false; let i = -1; let escStart = -1; let escEnd = -1; if (mode === FOLD_BLOCK) { i = consumeMoreIndentedLines(text, i); if (i !== -1) end2 = i + endStep; } for (let ch; ch = text[i += 1]; ) { if (mode === FOLD_QUOTED && ch === "\\") { escStart = i; switch (text[i + 1]) { case "x": i += 3; break; case "u": i += 5; break; case "U": i += 9; break; default: i += 1; } escEnd = i; } if (ch === "\n") { if (mode === FOLD_BLOCK) i = consumeMoreIndentedLines(text, i); end2 = i + endStep; split = void 0; } else { if (ch === " " && prev && prev !== " " && prev !== "\n" && prev !== " ") { const next = text[i + 1]; if (next && next !== " " && next !== "\n" && next !== " ") split = i; } if (i >= end2) { if (split) { folds.push(split); end2 = split + endStep; split = void 0; } else if (mode === FOLD_QUOTED) { while (prev === " " || prev === " ") { prev = ch; ch = text[i += 1]; overflow = true; } const j = i > escEnd + 1 ? i - 2 : escStart - 1; if (escapedFolds[j]) return text; folds.push(j); escapedFolds[j] = true; end2 = j + endStep; split = void 0; } else { overflow = true; } } } prev = ch; } if (overflow && onOverflow) onOverflow(); if (folds.length === 0) return text; if (onFold) onFold(); let res = text.slice(0, folds[0]); for (let i2 = 0; i2 < folds.length; ++i2) { const fold = folds[i2]; const end3 = folds[i2 + 1] || text.length; if (fold === 0) res = ` ${indent}${text.slice(0, end3)}`; else { if (mode === FOLD_QUOTED && escapedFolds[fold]) res += `${text[fold]}\\`; res += ` ${indent}${text.slice(fold + 1, end3)}`; } } return res; } function consumeMoreIndentedLines(text, i) { let ch = text[i + 1]; while (ch === " " || ch === " ") { do { ch = text[i += 1]; } while (ch && ch !== "\n"); ch = text[i + 1]; } return i; } // node_modules/yaml/browser/dist/stringify/stringifyString.js var getFoldOptions = (ctx, isBlock2) => ({ indentAtStart: isBlock2 ? ctx.indent.length : ctx.indentAtStart, lineWidth: ctx.options.lineWidth, minContentWidth: ctx.options.minContentWidth }); var containsDocumentMarker = (str) => /^(%|---|\.\.\.)/m.test(str); function lineLengthOverLimit(str, lineWidth, indentLength) { if (!lineWidth || lineWidth < 0) return false; const limit = lineWidth - indentLength; const strLen = str.length; if (strLen <= limit) return false; for (let i = 0, start2 = 0; i < strLen; ++i) { if (str[i] === "\n") { if (i - start2 > limit) return true; start2 = i + 1; if (strLen - start2 <= limit) return false; } } return true; } function doubleQuotedString(value, ctx) { const json2 = JSON.stringify(value); if (ctx.options.doubleQuotedAsJSON) return json2; const { implicitKey } = ctx; const minMultiLineLength = ctx.options.doubleQuotedMinMultiLineLength; const indent = ctx.indent || (containsDocumentMarker(value) ? " " : ""); let str = ""; let start2 = 0; for (let i = 0, ch = json2[i]; ch; ch = json2[++i]) { if (ch === " " && json2[i + 1] === "\\" && json2[i + 2] === "n") { str += json2.slice(start2, i) + "\\ "; i += 1; start2 = i; ch = "\\"; } if (ch === "\\") switch (json2[i + 1]) { case "u": { str += json2.slice(start2, i); const code = json2.substr(i + 2, 4); switch (code) { case "0000": str += "\\0"; break; case "0007": str += "\\a"; break; case "000b": str += "\\v"; break; case "001b": str += "\\e"; break; case "0085": str += "\\N"; break; case "00a0": str += "\\_"; break; case "2028": str += "\\L"; break; case "2029": str += "\\P"; break; default: if (code.substr(0, 2) === "00") str += "\\x" + code.substr(2); else str += json2.substr(i, 6); } i += 5; start2 = i + 1; } break; case "n": if (implicitKey || json2[i + 2] === '"' || json2.length < minMultiLineLength) { i += 1; } else { str += json2.slice(start2, i) + "\n\n"; while (json2[i + 2] === "\\" && json2[i + 3] === "n" && json2[i + 4] !== '"') { str += "\n"; i += 2; } str += indent; if (json2[i + 2] === " ") str += "\\"; i += 1; start2 = i + 1; } break; default: i += 1; } } str = start2 ? str + json2.slice(start2) : json2; return implicitKey ? str : foldFlowLines(str, indent, FOLD_QUOTED, getFoldOptions(ctx, false)); } function singleQuotedString(value, ctx) { if (ctx.options.singleQuote === false || ctx.implicitKey && value.includes("\n") || /[ \t]\n|\n[ \t]/.test(value)) return doubleQuotedString(value, ctx); const indent = ctx.indent || (containsDocumentMarker(value) ? " " : ""); const res = "'" + value.replace(/'/g, "''").replace(/\n+/g, `$& ${indent}`) + "'"; return ctx.implicitKey ? res : foldFlowLines(res, indent, FOLD_FLOW, getFoldOptions(ctx, false)); } function quotedString(value, ctx) { const { singleQuote } = ctx.options; let qs; if (singleQuote === false) qs = doubleQuotedString; else { const hasDouble = value.includes('"'); const hasSingle = value.includes("'"); if (hasDouble && !hasSingle) qs = singleQuotedString; else if (hasSingle && !hasDouble) qs = doubleQuotedString; else qs = singleQuote ? singleQuotedString : doubleQuotedString; } return qs(value, ctx); } var blockEndNewlines; try { blockEndNewlines = new RegExp("(^|(?\n"; let chomp; let endStart; for (endStart = value.length; endStart > 0; --endStart) { const ch = value[endStart - 1]; if (ch !== "\n" && ch !== " " && ch !== " ") break; } let end2 = value.substring(endStart); const endNlPos = end2.indexOf("\n"); if (endNlPos === -1) { chomp = "-"; } else if (value === end2 || endNlPos !== end2.length - 1) { chomp = "+"; if (onChompKeep) onChompKeep(); } else { chomp = ""; } if (end2) { value = value.slice(0, -end2.length); if (end2[end2.length - 1] === "\n") end2 = end2.slice(0, -1); end2 = end2.replace(blockEndNewlines, `$&${indent}`); } let startWithSpace = false; let startEnd; let startNlPos = -1; for (startEnd = 0; startEnd < value.length; ++startEnd) { const ch = value[startEnd]; if (ch === " ") startWithSpace = true; else if (ch === "\n") startNlPos = startEnd; else break; } let start2 = value.substring(0, startNlPos < startEnd ? startNlPos + 1 : startEnd); if (start2) { value = value.substring(start2.length); start2 = start2.replace(/\n+/g, `$&${indent}`); } const indentSize = indent ? "2" : "1"; let header = (literal ? "|" : ">") + (startWithSpace ? indentSize : "") + chomp; if (comment) { header += " " + commentString(comment.replace(/ ?[\r\n]+/g, " ")); if (onComment) onComment(); } if (literal) { value = value.replace(/\n+/g, `$&${indent}`); return `${header} ${indent}${start2}${value}${end2}`; } value = value.replace(/\n+/g, "\n$&").replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g, "$1$2").replace(/\n+/g, `$&${indent}`); const body = foldFlowLines(`${start2}${value}${end2}`, indent, FOLD_BLOCK, getFoldOptions(ctx, true)); return `${header} ${indent}${body}`; } function plainString(item, ctx, onComment, onChompKeep) { const { type, value } = item; const { actualString, implicitKey, indent, indentStep, inFlow } = ctx; if (implicitKey && value.includes("\n") || inFlow && /[[\]{},]/.test(value)) { return quotedString(value, ctx); } if (!value || /^[\n\t ,[\]{}#&*!|>'"%@`]|^[?-]$|^[?-][ \t]|[\n:][ \t]|[ \t]\n|[\n\t ]#|[\n\t :]$/.test(value)) { return implicitKey || inFlow || !value.includes("\n") ? quotedString(value, ctx) : blockString(item, ctx, onComment, onChompKeep); } if (!implicitKey && !inFlow && type !== Scalar.PLAIN && value.includes("\n")) { return blockString(item, ctx, onComment, onChompKeep); } if (containsDocumentMarker(value)) { if (indent === "") { ctx.forceBlockIndent = true; return blockString(item, ctx, onComment, onChompKeep); } else if (implicitKey && indent === indentStep) { return quotedString(value, ctx); } } const str = value.replace(/\n+/g, `$& ${indent}`); if (actualString) { const test = (tag) => { var _a; return tag.default && tag.tag !== "tag:yaml.org,2002:str" && ((_a = tag.test) == null ? void 0 : _a.test(str)); }; const { compat, tags: tags2 } = ctx.doc.schema; if (tags2.some(test) || (compat == null ? void 0 : compat.some(test))) return quotedString(value, ctx); } return implicitKey ? str : foldFlowLines(str, indent, FOLD_FLOW, getFoldOptions(ctx, false)); } function stringifyString(item, ctx, onComment, onChompKeep) { const { implicitKey, inFlow } = ctx; const ss = typeof item.value === "string" ? item : Object.assign({}, item, { value: String(item.value) }); let { type } = item; if (type !== Scalar.QUOTE_DOUBLE) { if (/[\x00-\x08\x0b-\x1f\x7f-\x9f\u{D800}-\u{DFFF}]/u.test(ss.value)) type = Scalar.QUOTE_DOUBLE; } const _stringify = (_type) => { switch (_type) { case Scalar.BLOCK_FOLDED: case Scalar.BLOCK_LITERAL: return implicitKey || inFlow ? quotedString(ss.value, ctx) : blockString(ss, ctx, onComment, onChompKeep); case Scalar.QUOTE_DOUBLE: return doubleQuotedString(ss.value, ctx); case Scalar.QUOTE_SINGLE: return singleQuotedString(ss.value, ctx); case Scalar.PLAIN: return plainString(ss, ctx, onComment, onChompKeep); default: return null; } }; let res = _stringify(type); if (res === null) { const { defaultKeyType, defaultStringType } = ctx.options; const t = implicitKey && defaultKeyType || defaultStringType; res = _stringify(t); if (res === null) throw new Error(`Unsupported default string type ${t}`); } return res; } // node_modules/yaml/browser/dist/stringify/stringify.js function createStringifyContext(doc, options2) { const opt = Object.assign({ blockQuote: true, commentString: stringifyComment, defaultKeyType: null, defaultStringType: "PLAIN", directives: null, doubleQuotedAsJSON: false, doubleQuotedMinMultiLineLength: 40, falseStr: "false", flowCollectionPadding: true, indentSeq: true, lineWidth: 80, minContentWidth: 20, nullStr: "null", simpleKeys: false, singleQuote: null, trueStr: "true", verifyAliasOrder: true }, doc.schema.toStringOptions, options2); let inFlow; switch (opt.collectionStyle) { case "block": inFlow = false; break; case "flow": inFlow = true; break; default: inFlow = null; } return { anchors: /* @__PURE__ */ new Set(), doc, flowCollectionPadding: opt.flowCollectionPadding ? " " : "", indent: "", indentStep: typeof opt.indent === "number" ? " ".repeat(opt.indent) : " ", inFlow, options: opt }; } function getTagObject(tags2, item) { var _a, _b, _c, _d; if (item.tag) { const match = tags2.filter((t) => t.tag === item.tag); if (match.length > 0) return (_a = match.find((t) => t.format === item.format)) != null ? _a : match[0]; } let tagObj = void 0; let obj; if (isScalar(item)) { obj = item.value; const match = tags2.filter((t) => { var _a2; return (_a2 = t.identify) == null ? void 0 : _a2.call(t, obj); }); tagObj = (_b = match.find((t) => t.format === item.format)) != null ? _b : match.find((t) => !t.format); } else { obj = item; tagObj = tags2.find((t) => t.nodeClass && obj instanceof t.nodeClass); } if (!tagObj) { const name = (_d = (_c = obj == null ? void 0 : obj.constructor) == null ? void 0 : _c.name) != null ? _d : typeof obj; throw new Error(`Tag not resolved for ${name} value`); } return tagObj; } function stringifyProps(node, tagObj, { anchors, doc }) { if (!doc.directives) return ""; const props = []; const anchor = (isScalar(node) || isCollection(node)) && node.anchor; if (anchor && anchorIsValid(anchor)) { anchors.add(anchor); props.push(`&${anchor}`); } const tag = node.tag ? node.tag : tagObj.default ? null : tagObj.tag; if (tag) props.push(doc.directives.tagString(tag)); return props.join(" "); } function stringify(item, ctx, onComment, onChompKeep) { var _a, _b; if (isPair(item)) return item.toString(ctx, onComment, onChompKeep); if (isAlias(item)) { if (ctx.doc.directives) return item.toString(ctx); if ((_a = ctx.resolvedAliases) == null ? void 0 : _a.has(item)) { throw new TypeError(`Cannot stringify circular structure without alias nodes`); } else { if (ctx.resolvedAliases) ctx.resolvedAliases.add(item); else ctx.resolvedAliases = /* @__PURE__ */ new Set([item]); item = item.resolve(ctx.doc); } } let tagObj = void 0; const node = isNode(item) ? item : ctx.doc.createNode(item, { onTagObj: (o) => tagObj = o }); if (!tagObj) tagObj = getTagObject(ctx.doc.schema.tags, node); const props = stringifyProps(node, tagObj, ctx); if (props.length > 0) ctx.indentAtStart = ((_b = ctx.indentAtStart) != null ? _b : 0) + props.length + 1; const str = typeof tagObj.stringify === "function" ? tagObj.stringify(node, ctx, onComment, onChompKeep) : isScalar(node) ? stringifyString(node, ctx, onComment, onChompKeep) : node.toString(ctx, onComment, onChompKeep); if (!props) return str; return isScalar(node) || str[0] === "{" || str[0] === "[" ? `${props} ${str}` : `${props} ${ctx.indent}${str}`; } // node_modules/yaml/browser/dist/stringify/stringifyPair.js function stringifyPair({ key, value }, ctx, onComment, onChompKeep) { var _a, _b; const { allNullValues, doc, indent, indentStep, options: { commentString, indentSeq, simpleKeys } } = ctx; let keyComment = isNode(key) && key.comment || null; if (simpleKeys) { if (keyComment) { throw new Error("With simple keys, key nodes cannot have comments"); } if (isCollection(key)) { const msg = "With simple keys, collection cannot be used as a key value"; throw new Error(msg); } } let explicitKey = !simpleKeys && (!key || keyComment && value == null && !ctx.inFlow || isCollection(key) || (isScalar(key) ? key.type === Scalar.BLOCK_FOLDED || key.type === Scalar.BLOCK_LITERAL : typeof key === "object")); ctx = Object.assign({}, ctx, { allNullValues: false, implicitKey: !explicitKey && (simpleKeys || !allNullValues), indent: indent + indentStep }); let keyCommentDone = false; let chompKeep = false; let str = stringify(key, ctx, () => keyCommentDone = true, () => chompKeep = true); if (!explicitKey && !ctx.inFlow && str.length > 1024) { if (simpleKeys) throw new Error("With simple keys, single line scalar must not span more than 1024 characters"); explicitKey = true; } if (ctx.inFlow) { if (allNullValues || value == null) { if (keyCommentDone && onComment) onComment(); return str === "" ? "?" : explicitKey ? `? ${str}` : str; } } else if (allNullValues && !simpleKeys || value == null && explicitKey) { str = `? ${str}`; if (keyComment && !keyCommentDone) { str += lineComment(str, ctx.indent, commentString(keyComment)); } else if (chompKeep && onChompKeep) onChompKeep(); return str; } if (keyCommentDone) keyComment = null; if (explicitKey) { if (keyComment) str += lineComment(str, ctx.indent, commentString(keyComment)); str = `? ${str} ${indent}:`; } else { str = `${str}:`; if (keyComment) str += lineComment(str, ctx.indent, commentString(keyComment)); } let vsb, vcb, valueComment; if (isNode(value)) { vsb = !!value.spaceBefore; vcb = value.commentBefore; valueComment = value.comment; } else { vsb = false; vcb = null; valueComment = null; if (value && typeof value === "object") value = doc.createNode(value); } ctx.implicitKey = false; if (!explicitKey && !keyComment && isScalar(value)) ctx.indentAtStart = str.length + 1; chompKeep = false; if (!indentSeq && indentStep.length >= 2 && !ctx.inFlow && !explicitKey && isSeq(value) && !value.flow && !value.tag && !value.anchor) { ctx.indent = ctx.indent.substring(2); } let valueCommentDone = false; const valueStr = stringify(value, ctx, () => valueCommentDone = true, () => chompKeep = true); let ws = " "; if (keyComment || vsb || vcb) { ws = vsb ? "\n" : ""; if (vcb) { const cs = commentString(vcb); ws += ` ${indentComment(cs, ctx.indent)}`; } if (valueStr === "" && !ctx.inFlow) { if (ws === "\n") ws = "\n\n"; } else { ws += ` ${ctx.indent}`; } } else if (!explicitKey && isCollection(value)) { const vs0 = valueStr[0]; const nl0 = valueStr.indexOf("\n"); const hasNewline = nl0 !== -1; const flow = (_b = (_a = ctx.inFlow) != null ? _a : value.flow) != null ? _b : value.items.length === 0; if (hasNewline || !flow) { let hasPropsLine = false; if (hasNewline && (vs0 === "&" || vs0 === "!")) { let sp0 = valueStr.indexOf(" "); if (vs0 === "&" && sp0 !== -1 && sp0 < nl0 && valueStr[sp0 + 1] === "!") { sp0 = valueStr.indexOf(" ", sp0 + 1); } if (sp0 === -1 || nl0 < sp0) hasPropsLine = true; } if (!hasPropsLine) ws = ` ${ctx.indent}`; } } else if (valueStr === "" || valueStr[0] === "\n") { ws = ""; } str += ws + valueStr; if (ctx.inFlow) { if (valueCommentDone && onComment) onComment(); } else if (valueComment && !valueCommentDone) { str += lineComment(str, ctx.indent, commentString(valueComment)); } else if (chompKeep && onChompKeep) { onChompKeep(); } return str; } // node_modules/yaml/browser/dist/log.js function warn(logLevel, warning) { if (logLevel === "debug" || logLevel === "warn") { if (typeof process !== "undefined" && process.emitWarning) process.emitWarning(warning); else console.warn(warning); } } // node_modules/yaml/browser/dist/nodes/addPairToJSMap.js var MERGE_KEY = "<<"; function addPairToJSMap(ctx, map2, { key, value }) { if ((ctx == null ? void 0 : ctx.doc.schema.merge) && isMergeKey(key)) { value = isAlias(value) ? value.resolve(ctx.doc) : value; if (isSeq(value)) for (const it of value.items) mergeToJSMap(ctx, map2, it); else if (Array.isArray(value)) for (const it of value) mergeToJSMap(ctx, map2, it); else mergeToJSMap(ctx, map2, value); } else { const jsKey = toJS(key, "", ctx); if (map2 instanceof Map) { map2.set(jsKey, toJS(value, jsKey, ctx)); } else if (map2 instanceof Set) { map2.add(jsKey); } else { const stringKey = stringifyKey(key, jsKey, ctx); const jsValue = toJS(value, stringKey, ctx); if (stringKey in map2) Object.defineProperty(map2, stringKey, { value: jsValue, writable: true, enumerable: true, configurable: true }); else map2[stringKey] = jsValue; } } return map2; } var isMergeKey = (key) => key === MERGE_KEY || isScalar(key) && key.value === MERGE_KEY && (!key.type || key.type === Scalar.PLAIN); function mergeToJSMap(ctx, map2, value) { const source = ctx && isAlias(value) ? value.resolve(ctx.doc) : value; if (!isMap(source)) throw new Error("Merge sources must be maps or map aliases"); const srcMap = source.toJSON(null, ctx, Map); for (const [key, value2] of srcMap) { if (map2 instanceof Map) { if (!map2.has(key)) map2.set(key, value2); } else if (map2 instanceof Set) { map2.add(key); } else if (!Object.prototype.hasOwnProperty.call(map2, key)) { Object.defineProperty(map2, key, { value: value2, writable: true, enumerable: true, configurable: true }); } } return map2; } function stringifyKey(key, jsKey, ctx) { if (jsKey === null) return ""; if (typeof jsKey !== "object") return String(jsKey); if (isNode(key) && (ctx == null ? void 0 : ctx.doc)) { const strCtx = createStringifyContext(ctx.doc, {}); strCtx.anchors = /* @__PURE__ */ new Set(); for (const node of ctx.anchors.keys()) strCtx.anchors.add(node.anchor); strCtx.inFlow = true; strCtx.inStringifyKey = true; const strKey = key.toString(strCtx); if (!ctx.mapKeyWarned) { let jsonStr = JSON.stringify(strKey); if (jsonStr.length > 40) jsonStr = jsonStr.substring(0, 36) + '..."'; warn(ctx.doc.options.logLevel, `Keys with collection values will be stringified due to JS Object restrictions: ${jsonStr}. Set mapAsMap: true to use object keys.`); ctx.mapKeyWarned = true; } return strKey; } return JSON.stringify(jsKey); } // node_modules/yaml/browser/dist/nodes/Pair.js function createPair(key, value, ctx) { const k = createNode(key, void 0, ctx); const v = createNode(value, void 0, ctx); return new Pair(k, v); } var Pair = class { constructor(key, value = null) { Object.defineProperty(this, NODE_TYPE, { value: PAIR }); this.key = key; this.value = value; } clone(schema4) { let { key, value } = this; if (isNode(key)) key = key.clone(schema4); if (isNode(value)) value = value.clone(schema4); return new Pair(key, value); } toJSON(_, ctx) { const pair = (ctx == null ? void 0 : ctx.mapAsMap) ? /* @__PURE__ */ new Map() : {}; return addPairToJSMap(ctx, pair, this); } toString(ctx, onComment, onChompKeep) { return (ctx == null ? void 0 : ctx.doc) ? stringifyPair(this, ctx, onComment, onChompKeep) : JSON.stringify(this); } }; // node_modules/yaml/browser/dist/stringify/stringifyCollection.js function stringifyCollection(collection, ctx, options2) { var _a; const flow = (_a = ctx.inFlow) != null ? _a : collection.flow; const stringify4 = flow ? stringifyFlowCollection : stringifyBlockCollection; return stringify4(collection, ctx, options2); } function stringifyBlockCollection({ comment, items }, ctx, { blockItemPrefix, flowChars, itemIndent, onChompKeep, onComment }) { const { indent, options: { commentString } } = ctx; const itemCtx = Object.assign({}, ctx, { indent: itemIndent, type: null }); let chompKeep = false; const lines = []; for (let i = 0; i < items.length; ++i) { const item = items[i]; let comment2 = null; if (isNode(item)) { if (!chompKeep && item.spaceBefore) lines.push(""); addCommentBefore(ctx, lines, item.commentBefore, chompKeep); if (item.comment) comment2 = item.comment; } else if (isPair(item)) { const ik = isNode(item.key) ? item.key : null; if (ik) { if (!chompKeep && ik.spaceBefore) lines.push(""); addCommentBefore(ctx, lines, ik.commentBefore, chompKeep); } } chompKeep = false; let str2 = stringify(item, itemCtx, () => comment2 = null, () => chompKeep = true); if (comment2) str2 += lineComment(str2, itemIndent, commentString(comment2)); if (chompKeep && comment2) chompKeep = false; lines.push(blockItemPrefix + str2); } let str; if (lines.length === 0) { str = flowChars.start + flowChars.end; } else { str = lines[0]; for (let i = 1; i < lines.length; ++i) { const line = lines[i]; str += line ? ` ${indent}${line}` : "\n"; } } if (comment) { str += "\n" + indentComment(commentString(comment), indent); if (onComment) onComment(); } else if (chompKeep && onChompKeep) onChompKeep(); return str; } function stringifyFlowCollection({ comment, items }, ctx, { flowChars, itemIndent, onComment }) { const { indent, indentStep, flowCollectionPadding: fcPadding, options: { commentString } } = ctx; itemIndent += indentStep; const itemCtx = Object.assign({}, ctx, { indent: itemIndent, inFlow: true, type: null }); let reqNewline = false; let linesAtValue = 0; const lines = []; for (let i = 0; i < items.length; ++i) { const item = items[i]; let comment2 = null; if (isNode(item)) { if (item.spaceBefore) lines.push(""); addCommentBefore(ctx, lines, item.commentBefore, false); if (item.comment) comment2 = item.comment; } else if (isPair(item)) { const ik = isNode(item.key) ? item.key : null; if (ik) { if (ik.spaceBefore) lines.push(""); addCommentBefore(ctx, lines, ik.commentBefore, false); if (ik.comment) reqNewline = true; } const iv = isNode(item.value) ? item.value : null; if (iv) { if (iv.comment) comment2 = iv.comment; if (iv.commentBefore) reqNewline = true; } else if (item.value == null && (ik == null ? void 0 : ik.comment)) { comment2 = ik.comment; } } if (comment2) reqNewline = true; let str2 = stringify(item, itemCtx, () => comment2 = null); if (i < items.length - 1) str2 += ","; if (comment2) str2 += lineComment(str2, itemIndent, commentString(comment2)); if (!reqNewline && (lines.length > linesAtValue || str2.includes("\n"))) reqNewline = true; lines.push(str2); linesAtValue = lines.length; } let str; const { start: start2, end: end2 } = flowChars; if (lines.length === 0) { str = start2 + end2; } else { if (!reqNewline) { const len = lines.reduce((sum, line) => sum + line.length + 2, 2); reqNewline = len > Collection.maxFlowStringSingleLineLength; } if (reqNewline) { str = start2; for (const line of lines) str += line ? ` ${indentStep}${indent}${line}` : "\n"; str += ` ${indent}${end2}`; } else { str = `${start2}${fcPadding}${lines.join(" ")}${fcPadding}${end2}`; } } if (comment) { str += lineComment(str, indent, commentString(comment)); if (onComment) onComment(); } return str; } function addCommentBefore({ indent, options: { commentString } }, lines, comment, chompKeep) { if (comment && chompKeep) comment = comment.replace(/^\n+/, ""); if (comment) { const ic = indentComment(commentString(comment), indent); lines.push(ic.trimStart()); } } // node_modules/yaml/browser/dist/nodes/YAMLMap.js function findPair(items, key) { const k = isScalar(key) ? key.value : key; for (const it of items) { if (isPair(it)) { if (it.key === key || it.key === k) return it; if (isScalar(it.key) && it.key.value === k) return it; } } return void 0; } var YAMLMap = class extends Collection { static get tagName() { return "tag:yaml.org,2002:map"; } constructor(schema4) { super(MAP, schema4); this.items = []; } /** * A generic collection parsing method that can be extended * to other node classes that inherit from YAMLMap */ static from(schema4, obj, ctx) { const { keepUndefined, replacer } = ctx; const map2 = new this(schema4); const add = (key, value) => { if (typeof replacer === "function") value = replacer.call(obj, key, value); else if (Array.isArray(replacer) && !replacer.includes(key)) return; if (value !== void 0 || keepUndefined) map2.items.push(createPair(key, value, ctx)); }; if (obj instanceof Map) { for (const [key, value] of obj) add(key, value); } else if (obj && typeof obj === "object") { for (const key of Object.keys(obj)) add(key, obj[key]); } if (typeof schema4.sortMapEntries === "function") { map2.items.sort(schema4.sortMapEntries); } return map2; } /** * Adds a value to the collection. * * @param overwrite - If not set `true`, using a key that is already in the * collection will throw. Otherwise, overwrites the previous value. */ add(pair, overwrite) { var _a; let _pair; if (isPair(pair)) _pair = pair; else if (!pair || typeof pair !== "object" || !("key" in pair)) { _pair = new Pair(pair, pair == null ? void 0 : pair.value); } else _pair = new Pair(pair.key, pair.value); const prev = findPair(this.items, _pair.key); const sortEntries = (_a = this.schema) == null ? void 0 : _a.sortMapEntries; if (prev) { if (!overwrite) throw new Error(`Key ${_pair.key} already set`); if (isScalar(prev.value) && isScalarValue(_pair.value)) prev.value.value = _pair.value; else prev.value = _pair.value; } else if (sortEntries) { const i = this.items.findIndex((item) => sortEntries(_pair, item) < 0); if (i === -1) this.items.push(_pair); else this.items.splice(i, 0, _pair); } else { this.items.push(_pair); } } delete(key) { const it = findPair(this.items, key); if (!it) return false; const del = this.items.splice(this.items.indexOf(it), 1); return del.length > 0; } get(key, keepScalar) { var _a; const it = findPair(this.items, key); const node = it == null ? void 0 : it.value; return (_a = !keepScalar && isScalar(node) ? node.value : node) != null ? _a : void 0; } has(key) { return !!findPair(this.items, key); } set(key, value) { this.add(new Pair(key, value), true); } /** * @param ctx - Conversion context, originally set in Document#toJS() * @param {Class} Type - If set, forces the returned collection type * @returns Instance of Type, Map, or Object */ toJSON(_, ctx, Type3) { const map2 = Type3 ? new Type3() : (ctx == null ? void 0 : ctx.mapAsMap) ? /* @__PURE__ */ new Map() : {}; if (ctx == null ? void 0 : ctx.onCreate) ctx.onCreate(map2); for (const item of this.items) addPairToJSMap(ctx, map2, item); return map2; } toString(ctx, onComment, onChompKeep) { if (!ctx) return JSON.stringify(this); for (const item of this.items) { if (!isPair(item)) throw new Error(`Map items must all be pairs; found ${JSON.stringify(item)} instead`); } if (!ctx.allNullValues && this.hasAllNullValues(false)) ctx = Object.assign({}, ctx, { allNullValues: true }); return stringifyCollection(this, ctx, { blockItemPrefix: "", flowChars: { start: "{", end: "}" }, itemIndent: ctx.indent || "", onChompKeep, onComment }); } }; // node_modules/yaml/browser/dist/schema/common/map.js var map = { collection: "map", default: true, nodeClass: YAMLMap, tag: "tag:yaml.org,2002:map", resolve(map2, onError) { if (!isMap(map2)) onError("Expected a mapping for this tag"); return map2; }, createNode: (schema4, obj, ctx) => YAMLMap.from(schema4, obj, ctx) }; // node_modules/yaml/browser/dist/nodes/YAMLSeq.js var YAMLSeq = class extends Collection { static get tagName() { return "tag:yaml.org,2002:seq"; } constructor(schema4) { super(SEQ, schema4); this.items = []; } add(value) { this.items.push(value); } /** * Removes a value from the collection. * * `key` must contain a representation of an integer for this to succeed. * It may be wrapped in a `Scalar`. * * @returns `true` if the item was found and removed. */ delete(key) { const idx = asItemIndex(key); if (typeof idx !== "number") return false; const del = this.items.splice(idx, 1); return del.length > 0; } get(key, keepScalar) { const idx = asItemIndex(key); if (typeof idx !== "number") return void 0; const it = this.items[idx]; return !keepScalar && isScalar(it) ? it.value : it; } /** * Checks if the collection includes a value with the key `key`. * * `key` must contain a representation of an integer for this to succeed. * It may be wrapped in a `Scalar`. */ has(key) { const idx = asItemIndex(key); return typeof idx === "number" && idx < this.items.length; } /** * Sets a value in this collection. For `!!set`, `value` needs to be a * boolean to add/remove the item from the set. * * If `key` does not contain a representation of an integer, this will throw. * It may be wrapped in a `Scalar`. */ set(key, value) { const idx = asItemIndex(key); if (typeof idx !== "number") throw new Error(`Expected a valid index, not ${key}.`); const prev = this.items[idx]; if (isScalar(prev) && isScalarValue(value)) prev.value = value; else this.items[idx] = value; } toJSON(_, ctx) { const seq2 = []; if (ctx == null ? void 0 : ctx.onCreate) ctx.onCreate(seq2); let i = 0; for (const item of this.items) seq2.push(toJS(item, String(i++), ctx)); return seq2; } toString(ctx, onComment, onChompKeep) { if (!ctx) return JSON.stringify(this); return stringifyCollection(this, ctx, { blockItemPrefix: "- ", flowChars: { start: "[", end: "]" }, itemIndent: (ctx.indent || "") + " ", onChompKeep, onComment }); } static from(schema4, obj, ctx) { const { replacer } = ctx; const seq2 = new this(schema4); if (obj && Symbol.iterator in Object(obj)) { let i = 0; for (let it of obj) { if (typeof replacer === "function") { const key = obj instanceof Set ? it : String(i++); it = replacer.call(obj, key, it); } seq2.items.push(createNode(it, void 0, ctx)); } } return seq2; } }; function asItemIndex(key) { let idx = isScalar(key) ? key.value : key; if (idx && typeof idx === "string") idx = Number(idx); return typeof idx === "number" && Number.isInteger(idx) && idx >= 0 ? idx : null; } // node_modules/yaml/browser/dist/schema/common/seq.js var seq = { collection: "seq", default: true, nodeClass: YAMLSeq, tag: "tag:yaml.org,2002:seq", resolve(seq2, onError) { if (!isSeq(seq2)) onError("Expected a sequence for this tag"); return seq2; }, createNode: (schema4, obj, ctx) => YAMLSeq.from(schema4, obj, ctx) }; // node_modules/yaml/browser/dist/schema/common/string.js var string = { identify: (value) => typeof value === "string", default: true, tag: "tag:yaml.org,2002:str", resolve: (str) => str, stringify(item, ctx, onComment, onChompKeep) { ctx = Object.assign({ actualString: true }, ctx); return stringifyString(item, ctx, onComment, onChompKeep); } }; // node_modules/yaml/browser/dist/schema/common/null.js var nullTag = { identify: (value) => value == null, createNode: () => new Scalar(null), default: true, tag: "tag:yaml.org,2002:null", test: /^(?:~|[Nn]ull|NULL)?$/, resolve: () => new Scalar(null), stringify: ({ source }, ctx) => typeof source === "string" && nullTag.test.test(source) ? source : ctx.options.nullStr }; // node_modules/yaml/browser/dist/schema/core/bool.js var boolTag = { identify: (value) => typeof value === "boolean", default: true, tag: "tag:yaml.org,2002:bool", test: /^(?:[Tt]rue|TRUE|[Ff]alse|FALSE)$/, resolve: (str) => new Scalar(str[0] === "t" || str[0] === "T"), stringify({ source, value }, ctx) { if (source && boolTag.test.test(source)) { const sv = source[0] === "t" || source[0] === "T"; if (value === sv) return source; } return value ? ctx.options.trueStr : ctx.options.falseStr; } }; // node_modules/yaml/browser/dist/stringify/stringifyNumber.js function stringifyNumber({ format: format2, minFractionDigits, tag, value }) { if (typeof value === "bigint") return String(value); const num = typeof value === "number" ? value : Number(value); if (!isFinite(num)) return isNaN(num) ? ".nan" : num < 0 ? "-.inf" : ".inf"; let n = JSON.stringify(value); if (!format2 && minFractionDigits && (!tag || tag === "tag:yaml.org,2002:float") && /^\d/.test(n)) { let i = n.indexOf("."); if (i < 0) { i = n.length; n += "."; } let d = minFractionDigits - (n.length - i - 1); while (d-- > 0) n += "0"; } return n; } // node_modules/yaml/browser/dist/schema/core/float.js var floatNaN = { identify: (value) => typeof value === "number", default: true, tag: "tag:yaml.org,2002:float", test: /^(?:[-+]?\.(?:inf|Inf|INF|nan|NaN|NAN))$/, resolve: (str) => str.slice(-3).toLowerCase() === "nan" ? NaN : str[0] === "-" ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY, stringify: stringifyNumber }; var floatExp = { identify: (value) => typeof value === "number", default: true, tag: "tag:yaml.org,2002:float", format: "EXP", test: /^[-+]?(?:\.[0-9]+|[0-9]+(?:\.[0-9]*)?)[eE][-+]?[0-9]+$/, resolve: (str) => parseFloat(str), stringify(node) { const num = Number(node.value); return isFinite(num) ? num.toExponential() : stringifyNumber(node); } }; var float = { identify: (value) => typeof value === "number", default: true, tag: "tag:yaml.org,2002:float", test: /^[-+]?(?:\.[0-9]+|[0-9]+\.[0-9]*)$/, resolve(str) { const node = new Scalar(parseFloat(str)); const dot = str.indexOf("."); if (dot !== -1 && str[str.length - 1] === "0") node.minFractionDigits = str.length - dot - 1; return node; }, stringify: stringifyNumber }; // node_modules/yaml/browser/dist/schema/core/int.js var intIdentify = (value) => typeof value === "bigint" || Number.isInteger(value); var intResolve = (str, offset2, radix, { intAsBigInt }) => intAsBigInt ? BigInt(str) : parseInt(str.substring(offset2), radix); function intStringify(node, radix, prefix) { const { value } = node; if (intIdentify(value) && value >= 0) return prefix + value.toString(radix); return stringifyNumber(node); } var intOct = { identify: (value) => intIdentify(value) && value >= 0, default: true, tag: "tag:yaml.org,2002:int", format: "OCT", test: /^0o[0-7]+$/, resolve: (str, _onError, opt) => intResolve(str, 2, 8, opt), stringify: (node) => intStringify(node, 8, "0o") }; var int = { identify: intIdentify, default: true, tag: "tag:yaml.org,2002:int", test: /^[-+]?[0-9]+$/, resolve: (str, _onError, opt) => intResolve(str, 0, 10, opt), stringify: stringifyNumber }; var intHex = { identify: (value) => intIdentify(value) && value >= 0, default: true, tag: "tag:yaml.org,2002:int", format: "HEX", test: /^0x[0-9a-fA-F]+$/, resolve: (str, _onError, opt) => intResolve(str, 2, 16, opt), stringify: (node) => intStringify(node, 16, "0x") }; // node_modules/yaml/browser/dist/schema/core/schema.js var schema = [ map, seq, string, nullTag, boolTag, intOct, int, intHex, floatNaN, floatExp, float ]; // node_modules/yaml/browser/dist/schema/json/schema.js function intIdentify2(value) { return typeof value === "bigint" || Number.isInteger(value); } var stringifyJSON = ({ value }) => JSON.stringify(value); var jsonScalars = [ { identify: (value) => typeof value === "string", default: true, tag: "tag:yaml.org,2002:str", resolve: (str) => str, stringify: stringifyJSON }, { identify: (value) => value == null, createNode: () => new Scalar(null), default: true, tag: "tag:yaml.org,2002:null", test: /^null$/, resolve: () => null, stringify: stringifyJSON }, { identify: (value) => typeof value === "boolean", default: true, tag: "tag:yaml.org,2002:bool", test: /^true|false$/, resolve: (str) => str === "true", stringify: stringifyJSON }, { identify: intIdentify2, default: true, tag: "tag:yaml.org,2002:int", test: /^-?(?:0|[1-9][0-9]*)$/, resolve: (str, _onError, { intAsBigInt }) => intAsBigInt ? BigInt(str) : parseInt(str, 10), stringify: ({ value }) => intIdentify2(value) ? value.toString() : JSON.stringify(value) }, { identify: (value) => typeof value === "number", default: true, tag: "tag:yaml.org,2002:float", test: /^-?(?:0|[1-9][0-9]*)(?:\.[0-9]*)?(?:[eE][-+]?[0-9]+)?$/, resolve: (str) => parseFloat(str), stringify: stringifyJSON } ]; var jsonError = { default: true, tag: "", test: /^/, resolve(str, onError) { onError(`Unresolved plain scalar ${JSON.stringify(str)}`); return str; } }; var schema2 = [map, seq].concat(jsonScalars, jsonError); // node_modules/yaml/browser/dist/schema/yaml-1.1/binary.js var binary = { identify: (value) => value instanceof Uint8Array, default: false, tag: "tag:yaml.org,2002:binary", /** * Returns a Buffer in node and an Uint8Array in browsers * * To use the resulting buffer as an image, you'll want to do something like: * * const blob = new Blob([buffer], { type: 'image/jpeg' }) * document.querySelector('#photo').src = URL.createObjectURL(blob) */ resolve(src, onError) { if (typeof Buffer === "function") { return Buffer.from(src, "base64"); } else if (typeof atob === "function") { const str = atob(src.replace(/[\n\r]/g, "")); const buffer = new Uint8Array(str.length); for (let i = 0; i < str.length; ++i) buffer[i] = str.charCodeAt(i); return buffer; } else { onError("This environment does not support reading binary tags; either Buffer or atob is required"); return src; } }, stringify({ comment, type, value }, ctx, onComment, onChompKeep) { const buf = value; let str; if (typeof Buffer === "function") { str = buf instanceof Buffer ? buf.toString("base64") : Buffer.from(buf.buffer).toString("base64"); } else if (typeof btoa === "function") { let s = ""; for (let i = 0; i < buf.length; ++i) s += String.fromCharCode(buf[i]); str = btoa(s); } else { throw new Error("This environment does not support writing binary tags; either Buffer or btoa is required"); } if (!type) type = Scalar.BLOCK_LITERAL; if (type !== Scalar.QUOTE_DOUBLE) { const lineWidth = Math.max(ctx.options.lineWidth - ctx.indent.length, ctx.options.minContentWidth); const n = Math.ceil(str.length / lineWidth); const lines = new Array(n); for (let i = 0, o = 0; i < n; ++i, o += lineWidth) { lines[i] = str.substr(o, lineWidth); } str = lines.join(type === Scalar.BLOCK_LITERAL ? "\n" : " "); } return stringifyString({ comment, type, value: str }, ctx, onComment, onChompKeep); } }; // node_modules/yaml/browser/dist/schema/yaml-1.1/pairs.js function resolvePairs(seq2, onError) { var _a; if (isSeq(seq2)) { for (let i = 0; i < seq2.items.length; ++i) { let item = seq2.items[i]; if (isPair(item)) continue; else if (isMap(item)) { if (item.items.length > 1) onError("Each pair must have its own sequence indicator"); const pair = item.items[0] || new Pair(new Scalar(null)); if (item.commentBefore) pair.key.commentBefore = pair.key.commentBefore ? `${item.commentBefore} ${pair.key.commentBefore}` : item.commentBefore; if (item.comment) { const cn = (_a = pair.value) != null ? _a : pair.key; cn.comment = cn.comment ? `${item.comment} ${cn.comment}` : item.comment; } item = pair; } seq2.items[i] = isPair(item) ? item : new Pair(item); } } else onError("Expected a sequence for this tag"); return seq2; } function createPairs(schema4, iterable, ctx) { const { replacer } = ctx; const pairs2 = new YAMLSeq(schema4); pairs2.tag = "tag:yaml.org,2002:pairs"; let i = 0; if (iterable && Symbol.iterator in Object(iterable)) for (let it of iterable) { if (typeof replacer === "function") it = replacer.call(iterable, String(i++), it); let key, value; if (Array.isArray(it)) { if (it.length === 2) { key = it[0]; value = it[1]; } else throw new TypeError(`Expected [key, value] tuple: ${it}`); } else if (it && it instanceof Object) { const keys = Object.keys(it); if (keys.length === 1) { key = keys[0]; value = it[key]; } else { throw new TypeError(`Expected tuple with one key, not ${keys.length} keys`); } } else { key = it; } pairs2.items.push(createPair(key, value, ctx)); } return pairs2; } var pairs = { collection: "seq", default: false, tag: "tag:yaml.org,2002:pairs", resolve: resolvePairs, createNode: createPairs }; // node_modules/yaml/browser/dist/schema/yaml-1.1/omap.js var YAMLOMap = class extends YAMLSeq { constructor() { super(); this.add = YAMLMap.prototype.add.bind(this); this.delete = YAMLMap.prototype.delete.bind(this); this.get = YAMLMap.prototype.get.bind(this); this.has = YAMLMap.prototype.has.bind(this); this.set = YAMLMap.prototype.set.bind(this); this.tag = YAMLOMap.tag; } /** * If `ctx` is given, the return type is actually `Map`, * but TypeScript won't allow widening the signature of a child method. */ toJSON(_, ctx) { if (!ctx) return super.toJSON(_); const map2 = /* @__PURE__ */ new Map(); if (ctx == null ? void 0 : ctx.onCreate) ctx.onCreate(map2); for (const pair of this.items) { let key, value; if (isPair(pair)) { key = toJS(pair.key, "", ctx); value = toJS(pair.value, key, ctx); } else { key = toJS(pair, "", ctx); } if (map2.has(key)) throw new Error("Ordered maps must not include duplicate keys"); map2.set(key, value); } return map2; } static from(schema4, iterable, ctx) { const pairs2 = createPairs(schema4, iterable, ctx); const omap2 = new this(); omap2.items = pairs2.items; return omap2; } }; YAMLOMap.tag = "tag:yaml.org,2002:omap"; var omap = { collection: "seq", identify: (value) => value instanceof Map, nodeClass: YAMLOMap, default: false, tag: "tag:yaml.org,2002:omap", resolve(seq2, onError) { const pairs2 = resolvePairs(seq2, onError); const seenKeys = []; for (const { key } of pairs2.items) { if (isScalar(key)) { if (seenKeys.includes(key.value)) { onError(`Ordered maps must not include duplicate keys: ${key.value}`); } else { seenKeys.push(key.value); } } } return Object.assign(new YAMLOMap(), pairs2); }, createNode: (schema4, iterable, ctx) => YAMLOMap.from(schema4, iterable, ctx) }; // node_modules/yaml/browser/dist/schema/yaml-1.1/bool.js function boolStringify({ value, source }, ctx) { const boolObj = value ? trueTag : falseTag; if (source && boolObj.test.test(source)) return source; return value ? ctx.options.trueStr : ctx.options.falseStr; } var trueTag = { identify: (value) => value === true, default: true, tag: "tag:yaml.org,2002:bool", test: /^(?:Y|y|[Yy]es|YES|[Tt]rue|TRUE|[Oo]n|ON)$/, resolve: () => new Scalar(true), stringify: boolStringify }; var falseTag = { identify: (value) => value === false, default: true, tag: "tag:yaml.org,2002:bool", test: /^(?:N|n|[Nn]o|NO|[Ff]alse|FALSE|[Oo]ff|OFF)$/i, resolve: () => new Scalar(false), stringify: boolStringify }; // node_modules/yaml/browser/dist/schema/yaml-1.1/float.js var floatNaN2 = { identify: (value) => typeof value === "number", default: true, tag: "tag:yaml.org,2002:float", test: /^[-+]?\.(?:inf|Inf|INF|nan|NaN|NAN)$/, resolve: (str) => str.slice(-3).toLowerCase() === "nan" ? NaN : str[0] === "-" ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY, stringify: stringifyNumber }; var floatExp2 = { identify: (value) => typeof value === "number", default: true, tag: "tag:yaml.org,2002:float", format: "EXP", test: /^[-+]?(?:[0-9][0-9_]*)?(?:\.[0-9_]*)?[eE][-+]?[0-9]+$/, resolve: (str) => parseFloat(str.replace(/_/g, "")), stringify(node) { const num = Number(node.value); return isFinite(num) ? num.toExponential() : stringifyNumber(node); } }; var float2 = { identify: (value) => typeof value === "number", default: true, tag: "tag:yaml.org,2002:float", test: /^[-+]?(?:[0-9][0-9_]*)?\.[0-9_]*$/, resolve(str) { const node = new Scalar(parseFloat(str.replace(/_/g, ""))); const dot = str.indexOf("."); if (dot !== -1) { const f = str.substring(dot + 1).replace(/_/g, ""); if (f[f.length - 1] === "0") node.minFractionDigits = f.length; } return node; }, stringify: stringifyNumber }; // node_modules/yaml/browser/dist/schema/yaml-1.1/int.js var intIdentify3 = (value) => typeof value === "bigint" || Number.isInteger(value); function intResolve2(str, offset2, radix, { intAsBigInt }) { const sign = str[0]; if (sign === "-" || sign === "+") offset2 += 1; str = str.substring(offset2).replace(/_/g, ""); if (intAsBigInt) { switch (radix) { case 2: str = `0b${str}`; break; case 8: str = `0o${str}`; break; case 16: str = `0x${str}`; break; } const n2 = BigInt(str); return sign === "-" ? BigInt(-1) * n2 : n2; } const n = parseInt(str, radix); return sign === "-" ? -1 * n : n; } function intStringify2(node, radix, prefix) { const { value } = node; if (intIdentify3(value)) { const str = value.toString(radix); return value < 0 ? "-" + prefix + str.substr(1) : prefix + str; } return stringifyNumber(node); } var intBin = { identify: intIdentify3, default: true, tag: "tag:yaml.org,2002:int", format: "BIN", test: /^[-+]?0b[0-1_]+$/, resolve: (str, _onError, opt) => intResolve2(str, 2, 2, opt), stringify: (node) => intStringify2(node, 2, "0b") }; var intOct2 = { identify: intIdentify3, default: true, tag: "tag:yaml.org,2002:int", format: "OCT", test: /^[-+]?0[0-7_]+$/, resolve: (str, _onError, opt) => intResolve2(str, 1, 8, opt), stringify: (node) => intStringify2(node, 8, "0") }; var int2 = { identify: intIdentify3, default: true, tag: "tag:yaml.org,2002:int", test: /^[-+]?[0-9][0-9_]*$/, resolve: (str, _onError, opt) => intResolve2(str, 0, 10, opt), stringify: stringifyNumber }; var intHex2 = { identify: intIdentify3, default: true, tag: "tag:yaml.org,2002:int", format: "HEX", test: /^[-+]?0x[0-9a-fA-F_]+$/, resolve: (str, _onError, opt) => intResolve2(str, 2, 16, opt), stringify: (node) => intStringify2(node, 16, "0x") }; // node_modules/yaml/browser/dist/schema/yaml-1.1/set.js var YAMLSet = class extends YAMLMap { constructor(schema4) { super(schema4); this.tag = YAMLSet.tag; } add(key) { let pair; if (isPair(key)) pair = key; else if (key && typeof key === "object" && "key" in key && "value" in key && key.value === null) pair = new Pair(key.key, null); else pair = new Pair(key, null); const prev = findPair(this.items, pair.key); if (!prev) this.items.push(pair); } /** * If `keepPair` is `true`, returns the Pair matching `key`. * Otherwise, returns the value of that Pair's key. */ get(key, keepPair) { const pair = findPair(this.items, key); return !keepPair && isPair(pair) ? isScalar(pair.key) ? pair.key.value : pair.key : pair; } set(key, value) { if (typeof value !== "boolean") throw new Error(`Expected boolean value for set(key, value) in a YAML set, not ${typeof value}`); const prev = findPair(this.items, key); if (prev && !value) { this.items.splice(this.items.indexOf(prev), 1); } else if (!prev && value) { this.items.push(new Pair(key)); } } toJSON(_, ctx) { return super.toJSON(_, ctx, Set); } toString(ctx, onComment, onChompKeep) { if (!ctx) return JSON.stringify(this); if (this.hasAllNullValues(true)) return super.toString(Object.assign({}, ctx, { allNullValues: true }), onComment, onChompKeep); else throw new Error("Set items must all have null values"); } static from(schema4, iterable, ctx) { const { replacer } = ctx; const set2 = new this(schema4); if (iterable && Symbol.iterator in Object(iterable)) for (let value of iterable) { if (typeof replacer === "function") value = replacer.call(iterable, value, value); set2.items.push(createPair(value, null, ctx)); } return set2; } }; YAMLSet.tag = "tag:yaml.org,2002:set"; var set = { collection: "map", identify: (value) => value instanceof Set, nodeClass: YAMLSet, default: false, tag: "tag:yaml.org,2002:set", createNode: (schema4, iterable, ctx) => YAMLSet.from(schema4, iterable, ctx), resolve(map2, onError) { if (isMap(map2)) { if (map2.hasAllNullValues(true)) return Object.assign(new YAMLSet(), map2); else onError("Set items must all have null values"); } else onError("Expected a mapping for this tag"); return map2; } }; // node_modules/yaml/browser/dist/schema/yaml-1.1/timestamp.js function parseSexagesimal(str, asBigInt) { const sign = str[0]; const parts = sign === "-" || sign === "+" ? str.substring(1) : str; const num = (n) => asBigInt ? BigInt(n) : Number(n); const res = parts.replace(/_/g, "").split(":").reduce((res2, p) => res2 * num(60) + num(p), num(0)); return sign === "-" ? num(-1) * res : res; } function stringifySexagesimal(node) { let { value } = node; let num = (n) => n; if (typeof value === "bigint") num = (n) => BigInt(n); else if (isNaN(value) || !isFinite(value)) return stringifyNumber(node); let sign = ""; if (value < 0) { sign = "-"; value *= num(-1); } const _60 = num(60); const parts = [value % _60]; if (value < 60) { parts.unshift(0); } else { value = (value - parts[0]) / _60; parts.unshift(value % _60); if (value >= 60) { value = (value - parts[0]) / _60; parts.unshift(value); } } return sign + parts.map((n) => String(n).padStart(2, "0")).join(":").replace(/000000\d*$/, ""); } var intTime = { identify: (value) => typeof value === "bigint" || Number.isInteger(value), default: true, tag: "tag:yaml.org,2002:int", format: "TIME", test: /^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+$/, resolve: (str, _onError, { intAsBigInt }) => parseSexagesimal(str, intAsBigInt), stringify: stringifySexagesimal }; var floatTime = { identify: (value) => typeof value === "number", default: true, tag: "tag:yaml.org,2002:float", format: "TIME", test: /^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\.[0-9_]*$/, resolve: (str) => parseSexagesimal(str, false), stringify: stringifySexagesimal }; var timestamp = { identify: (value) => value instanceof Date, default: true, tag: "tag:yaml.org,2002:timestamp", // If the time zone is omitted, the timestamp is assumed to be specified in UTC. The time part // may be omitted altogether, resulting in a date format. In such a case, the time part is // assumed to be 00:00:00Z (start of day, UTC). test: RegExp("^([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})(?:(?:t|T|[ \\t]+)([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2}(\\.[0-9]+)?)(?:[ \\t]*(Z|[-+][012]?[0-9](?::[0-9]{2})?))?)?$"), resolve(str) { const match = str.match(timestamp.test); if (!match) throw new Error("!!timestamp expects a date, starting with yyyy-mm-dd"); const [, year, month, day, hour, minute, second] = match.map(Number); const millisec = match[7] ? Number((match[7] + "00").substr(1, 3)) : 0; let date = Date.UTC(year, month - 1, day, hour || 0, minute || 0, second || 0, millisec); const tz = match[8]; if (tz && tz !== "Z") { let d = parseSexagesimal(tz, false); if (Math.abs(d) < 30) d *= 60; date -= 6e4 * d; } return new Date(date); }, stringify: ({ value }) => value.toISOString().replace(/((T00:00)?:00)?\.000Z$/, "") }; // node_modules/yaml/browser/dist/schema/yaml-1.1/schema.js var schema3 = [ map, seq, string, nullTag, trueTag, falseTag, intBin, intOct2, int2, intHex2, floatNaN2, floatExp2, float2, binary, omap, pairs, set, intTime, floatTime, timestamp ]; // node_modules/yaml/browser/dist/schema/tags.js var schemas = /* @__PURE__ */ new Map([ ["core", schema], ["failsafe", [map, seq, string]], ["json", schema2], ["yaml11", schema3], ["yaml-1.1", schema3] ]); var tagsByName = { binary, bool: boolTag, float, floatExp, floatNaN, floatTime, int, intHex, intOct, intTime, map, null: nullTag, omap, pairs, seq, set, timestamp }; var coreKnownTags = { "tag:yaml.org,2002:binary": binary, "tag:yaml.org,2002:omap": omap, "tag:yaml.org,2002:pairs": pairs, "tag:yaml.org,2002:set": set, "tag:yaml.org,2002:timestamp": timestamp }; function getTags(customTags, schemaName) { let tags2 = schemas.get(schemaName); if (!tags2) { if (Array.isArray(customTags)) tags2 = []; else { const keys = Array.from(schemas.keys()).filter((key) => key !== "yaml11").map((key) => JSON.stringify(key)).join(", "); throw new Error(`Unknown schema "${schemaName}"; use one of ${keys} or define customTags array`); } } if (Array.isArray(customTags)) { for (const tag of customTags) tags2 = tags2.concat(tag); } else if (typeof customTags === "function") { tags2 = customTags(tags2.slice()); } return tags2.map((tag) => { if (typeof tag !== "string") return tag; const tagObj = tagsByName[tag]; if (tagObj) return tagObj; const keys = Object.keys(tagsByName).map((key) => JSON.stringify(key)).join(", "); throw new Error(`Unknown custom tag "${tag}"; use one of ${keys}`); }); } // node_modules/yaml/browser/dist/schema/Schema.js var sortMapEntriesByKey = (a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0; var Schema = class { constructor({ compat, customTags, merge, resolveKnownTags, schema: schema4, sortMapEntries, toStringDefaults }) { this.compat = Array.isArray(compat) ? getTags(compat, "compat") : compat ? getTags(null, compat) : null; this.merge = !!merge; this.name = typeof schema4 === "string" && schema4 || "core"; this.knownTags = resolveKnownTags ? coreKnownTags : {}; this.tags = getTags(customTags, this.name); this.toStringOptions = toStringDefaults != null ? toStringDefaults : null; Object.defineProperty(this, MAP, { value: map }); Object.defineProperty(this, SCALAR, { value: string }); Object.defineProperty(this, SEQ, { value: seq }); this.sortMapEntries = typeof sortMapEntries === "function" ? sortMapEntries : sortMapEntries === true ? sortMapEntriesByKey : null; } clone() { const copy = Object.create(Schema.prototype, Object.getOwnPropertyDescriptors(this)); copy.tags = this.tags.slice(); return copy; } }; // node_modules/yaml/browser/dist/stringify/stringifyDocument.js function stringifyDocument(doc, options2) { var _a; const lines = []; let hasDirectives = options2.directives === true; if (options2.directives !== false && doc.directives) { const dir = doc.directives.toString(doc); if (dir) { lines.push(dir); hasDirectives = true; } else if (doc.directives.docStart) hasDirectives = true; } if (hasDirectives) lines.push("---"); const ctx = createStringifyContext(doc, options2); const { commentString } = ctx.options; if (doc.commentBefore) { if (lines.length !== 1) lines.unshift(""); const cs = commentString(doc.commentBefore); lines.unshift(indentComment(cs, "")); } let chompKeep = false; let contentComment = null; if (doc.contents) { if (isNode(doc.contents)) { if (doc.contents.spaceBefore && hasDirectives) lines.push(""); if (doc.contents.commentBefore) { const cs = commentString(doc.contents.commentBefore); lines.push(indentComment(cs, "")); } ctx.forceBlockIndent = !!doc.comment; contentComment = doc.contents.comment; } const onChompKeep = contentComment ? void 0 : () => chompKeep = true; let body = stringify(doc.contents, ctx, () => contentComment = null, onChompKeep); if (contentComment) body += lineComment(body, "", commentString(contentComment)); if ((body[0] === "|" || body[0] === ">") && lines[lines.length - 1] === "---") { lines[lines.length - 1] = `--- ${body}`; } else lines.push(body); } else { lines.push(stringify(doc.contents, ctx)); } if ((_a = doc.directives) == null ? void 0 : _a.docEnd) { if (doc.comment) { const cs = commentString(doc.comment); if (cs.includes("\n")) { lines.push("..."); lines.push(indentComment(cs, "")); } else { lines.push(`... ${cs}`); } } else { lines.push("..."); } } else { let dc = doc.comment; if (dc && chompKeep) dc = dc.replace(/^\n+/, ""); if (dc) { if ((!chompKeep || contentComment) && lines[lines.length - 1] !== "") lines.push(""); lines.push(indentComment(commentString(dc), "")); } } return lines.join("\n") + "\n"; } // node_modules/yaml/browser/dist/doc/Document.js var Document = class { constructor(value, replacer, options2) { this.commentBefore = null; this.comment = null; this.errors = []; this.warnings = []; Object.defineProperty(this, NODE_TYPE, { value: DOC }); let _replacer = null; if (typeof replacer === "function" || Array.isArray(replacer)) { _replacer = replacer; } else if (options2 === void 0 && replacer) { options2 = replacer; replacer = void 0; } const opt = Object.assign({ intAsBigInt: false, keepSourceTokens: false, logLevel: "warn", prettyErrors: true, strict: true, uniqueKeys: true, version: "1.2" }, options2); this.options = opt; let { version } = opt; if (options2 == null ? void 0 : options2._directives) { this.directives = options2._directives.atDocument(); if (this.directives.yaml.explicit) version = this.directives.yaml.version; } else this.directives = new Directives({ version }); this.setSchema(version, options2); this.contents = value === void 0 ? null : this.createNode(value, _replacer, options2); } /** * Create a deep copy of this Document and its contents. * * Custom Node values that inherit from `Object` still refer to their original instances. */ clone() { const copy = Object.create(Document.prototype, { [NODE_TYPE]: { value: DOC } }); copy.commentBefore = this.commentBefore; copy.comment = this.comment; copy.errors = this.errors.slice(); copy.warnings = this.warnings.slice(); copy.options = Object.assign({}, this.options); if (this.directives) copy.directives = this.directives.clone(); copy.schema = this.schema.clone(); copy.contents = isNode(this.contents) ? this.contents.clone(copy.schema) : this.contents; if (this.range) copy.range = this.range.slice(); return copy; } /** Adds a value to the document. */ add(value) { if (assertCollection(this.contents)) this.contents.add(value); } /** Adds a value to the document. */ addIn(path, value) { if (assertCollection(this.contents)) this.contents.addIn(path, value); } /** * Create a new `Alias` node, ensuring that the target `node` has the required anchor. * * If `node` already has an anchor, `name` is ignored. * Otherwise, the `node.anchor` value will be set to `name`, * or if an anchor with that name is already present in the document, * `name` will be used as a prefix for a new unique anchor. * If `name` is undefined, the generated anchor will use 'a' as a prefix. */ createAlias(node, name) { if (!node.anchor) { const prev = anchorNames(this); node.anchor = // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing !name || prev.has(name) ? findNewAnchor(name || "a", prev) : name; } return new Alias(node.anchor); } createNode(value, replacer, options2) { let _replacer = void 0; if (typeof replacer === "function") { value = replacer.call({ "": value }, "", value); _replacer = replacer; } else if (Array.isArray(replacer)) { const keyToStr = (v) => typeof v === "number" || v instanceof String || v instanceof Number; const asStr = replacer.filter(keyToStr).map(String); if (asStr.length > 0) replacer = replacer.concat(asStr); _replacer = replacer; } else if (options2 === void 0 && replacer) { options2 = replacer; replacer = void 0; } const { aliasDuplicateObjects, anchorPrefix, flow, keepUndefined, onTagObj, tag } = options2 != null ? options2 : {}; const { onAnchor, setAnchors, sourceObjects } = createNodeAnchors( this, // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing anchorPrefix || "a" ); const ctx = { aliasDuplicateObjects: aliasDuplicateObjects != null ? aliasDuplicateObjects : true, keepUndefined: keepUndefined != null ? keepUndefined : false, onAnchor, onTagObj, replacer: _replacer, schema: this.schema, sourceObjects }; const node = createNode(value, tag, ctx); if (flow && isCollection(node)) node.flow = true; setAnchors(); return node; } /** * Convert a key and a value into a `Pair` using the current schema, * recursively wrapping all values as `Scalar` or `Collection` nodes. */ createPair(key, value, options2 = {}) { const k = this.createNode(key, null, options2); const v = this.createNode(value, null, options2); return new Pair(k, v); } /** * Removes a value from the document. * @returns `true` if the item was found and removed. */ delete(key) { return assertCollection(this.contents) ? this.contents.delete(key) : false; } /** * Removes a value from the document. * @returns `true` if the item was found and removed. */ deleteIn(path) { if (isEmptyPath(path)) { if (this.contents == null) return false; this.contents = null; return true; } return assertCollection(this.contents) ? this.contents.deleteIn(path) : false; } /** * Returns item at `key`, or `undefined` if not found. By default unwraps * scalar values from their surrounding node; to disable set `keepScalar` to * `true` (collections are always returned intact). */ get(key, keepScalar) { return isCollection(this.contents) ? this.contents.get(key, keepScalar) : void 0; } /** * Returns item at `path`, or `undefined` if not found. By default unwraps * scalar values from their surrounding node; to disable set `keepScalar` to * `true` (collections are always returned intact). */ getIn(path, keepScalar) { if (isEmptyPath(path)) return !keepScalar && isScalar(this.contents) ? this.contents.value : this.contents; return isCollection(this.contents) ? this.contents.getIn(path, keepScalar) : void 0; } /** * Checks if the document includes a value with the key `key`. */ has(key) { return isCollection(this.contents) ? this.contents.has(key) : false; } /** * Checks if the document includes a value at `path`. */ hasIn(path) { if (isEmptyPath(path)) return this.contents !== void 0; return isCollection(this.contents) ? this.contents.hasIn(path) : false; } /** * Sets a value in this document. For `!!set`, `value` needs to be a * boolean to add/remove the item from the set. */ set(key, value) { if (this.contents == null) { this.contents = collectionFromPath(this.schema, [key], value); } else if (assertCollection(this.contents)) { this.contents.set(key, value); } } /** * Sets a value in this document. For `!!set`, `value` needs to be a * boolean to add/remove the item from the set. */ setIn(path, value) { if (isEmptyPath(path)) { this.contents = value; } else if (this.contents == null) { this.contents = collectionFromPath(this.schema, Array.from(path), value); } else if (assertCollection(this.contents)) { this.contents.setIn(path, value); } } /** * Change the YAML version and schema used by the document. * A `null` version disables support for directives, explicit tags, anchors, and aliases. * It also requires the `schema` option to be given as a `Schema` instance value. * * Overrides all previously set schema options. */ setSchema(version, options2 = {}) { if (typeof version === "number") version = String(version); let opt; switch (version) { case "1.1": if (this.directives) this.directives.yaml.version = "1.1"; else this.directives = new Directives({ version: "1.1" }); opt = { merge: true, resolveKnownTags: false, schema: "yaml-1.1" }; break; case "1.2": case "next": if (this.directives) this.directives.yaml.version = version; else this.directives = new Directives({ version }); opt = { merge: false, resolveKnownTags: true, schema: "core" }; break; case null: if (this.directives) delete this.directives; opt = null; break; default: { const sv = JSON.stringify(version); throw new Error(`Expected '1.1', '1.2' or null as first argument, but found: ${sv}`); } } if (options2.schema instanceof Object) this.schema = options2.schema; else if (opt) this.schema = new Schema(Object.assign(opt, options2)); else throw new Error(`With a null YAML version, the { schema: Schema } option is required`); } // json & jsonArg are only used from toJSON() toJS({ json: json2, jsonArg, mapAsMap, maxAliasCount, onAnchor, reviver } = {}) { const ctx = { anchors: /* @__PURE__ */ new Map(), doc: this, keep: !json2, mapAsMap: mapAsMap === true, mapKeyWarned: false, maxAliasCount: typeof maxAliasCount === "number" ? maxAliasCount : 100 }; const res = toJS(this.contents, jsonArg != null ? jsonArg : "", ctx); if (typeof onAnchor === "function") for (const { count, res: res2 } of ctx.anchors.values()) onAnchor(res2, count); return typeof reviver === "function" ? applyReviver(reviver, { "": res }, "", res) : res; } /** * A JSON representation of the document `contents`. * * @param jsonArg Used by `JSON.stringify` to indicate the array index or * property name. */ toJSON(jsonArg, onAnchor) { return this.toJS({ json: true, jsonArg, mapAsMap: false, onAnchor }); } /** A YAML representation of the document. */ toString(options2 = {}) { if (this.errors.length > 0) throw new Error("Document with errors cannot be stringified"); if ("indent" in options2 && (!Number.isInteger(options2.indent) || Number(options2.indent) <= 0)) { const s = JSON.stringify(options2.indent); throw new Error(`"indent" option must be a positive integer, not ${s}`); } return stringifyDocument(this, options2); } }; function assertCollection(contents) { if (isCollection(contents)) return true; throw new Error("Expected a YAML collection as document contents"); } // node_modules/yaml/browser/dist/errors.js var YAMLError = class extends Error { constructor(name, pos, code, message) { super(); this.name = name; this.code = code; this.message = message; this.pos = pos; } }; var YAMLParseError = class extends YAMLError { constructor(pos, code, message) { super("YAMLParseError", pos, code, message); } }; var YAMLWarning = class extends YAMLError { constructor(pos, code, message) { super("YAMLWarning", pos, code, message); } }; var prettifyError = (src, lc) => (error) => { if (error.pos[0] === -1) return; error.linePos = error.pos.map((pos) => lc.linePos(pos)); const { line, col } = error.linePos[0]; error.message += ` at line ${line}, column ${col}`; let ci = col - 1; let lineStr = src.substring(lc.lineStarts[line - 1], lc.lineStarts[line]).replace(/[\n\r]+$/, ""); if (ci >= 60 && lineStr.length > 80) { const trimStart = Math.min(ci - 39, lineStr.length - 79); lineStr = "\u2026" + lineStr.substring(trimStart); ci -= trimStart - 1; } if (lineStr.length > 80) lineStr = lineStr.substring(0, 79) + "\u2026"; if (line > 1 && /^ *$/.test(lineStr.substring(0, ci))) { let prev = src.substring(lc.lineStarts[line - 2], lc.lineStarts[line - 1]); if (prev.length > 80) prev = prev.substring(0, 79) + "\u2026\n"; lineStr = prev + lineStr; } if (/[^ ]/.test(lineStr)) { let count = 1; const end2 = error.linePos[1]; if (end2 && end2.line === line && end2.col > col) { count = Math.max(1, Math.min(end2.col - col, 80 - ci)); } const pointer = " ".repeat(ci) + "^".repeat(count); error.message += `: ${lineStr} ${pointer} `; } }; // node_modules/yaml/browser/dist/compose/resolve-props.js function resolveProps(tokens, { flow, indicator, next, offset: offset2, onError, startOnNewline }) { let spaceBefore = false; let atNewline = startOnNewline; let hasSpace = startOnNewline; let comment = ""; let commentSep = ""; let hasNewline = false; let hasNewlineAfterProp = false; let reqSpace = false; let anchor = null; let tag = null; let comma = null; let found = null; let start2 = null; for (const token of tokens) { if (reqSpace) { if (token.type !== "space" && token.type !== "newline" && token.type !== "comma") onError(token.offset, "MISSING_CHAR", "Tags and anchors must be separated from the next token by white space"); reqSpace = false; } switch (token.type) { case "space": if (!flow && atNewline && indicator !== "doc-start" && token.source[0] === " ") onError(token, "TAB_AS_INDENT", "Tabs are not allowed as indentation"); hasSpace = true; break; case "comment": { if (!hasSpace) onError(token, "MISSING_CHAR", "Comments must be separated from other tokens by white space characters"); const cb = token.source.substring(1) || " "; if (!comment) comment = cb; else comment += commentSep + cb; commentSep = ""; atNewline = false; break; } case "newline": if (atNewline) { if (comment) comment += token.source; else spaceBefore = true; } else commentSep += token.source; atNewline = true; hasNewline = true; if (anchor || tag) hasNewlineAfterProp = true; hasSpace = true; break; case "anchor": if (anchor) onError(token, "MULTIPLE_ANCHORS", "A node can have at most one anchor"); if (token.source.endsWith(":")) onError(token.offset + token.source.length - 1, "BAD_ALIAS", "Anchor ending in : is ambiguous", true); anchor = token; if (start2 === null) start2 = token.offset; atNewline = false; hasSpace = false; reqSpace = true; break; case "tag": { if (tag) onError(token, "MULTIPLE_TAGS", "A node can have at most one tag"); tag = token; if (start2 === null) start2 = token.offset; atNewline = false; hasSpace = false; reqSpace = true; break; } case indicator: if (anchor || tag) onError(token, "BAD_PROP_ORDER", `Anchors and tags must be after the ${token.source} indicator`); if (found) onError(token, "UNEXPECTED_TOKEN", `Unexpected ${token.source} in ${flow != null ? flow : "collection"}`); found = token; atNewline = false; hasSpace = false; break; case "comma": if (flow) { if (comma) onError(token, "UNEXPECTED_TOKEN", `Unexpected , in ${flow}`); comma = token; atNewline = false; hasSpace = false; break; } default: onError(token, "UNEXPECTED_TOKEN", `Unexpected ${token.type} token`); atNewline = false; hasSpace = false; } } const last = tokens[tokens.length - 1]; const end2 = last ? last.offset + last.source.length : offset2; if (reqSpace && next && next.type !== "space" && next.type !== "newline" && next.type !== "comma" && (next.type !== "scalar" || next.source !== "")) onError(next.offset, "MISSING_CHAR", "Tags and anchors must be separated from the next token by white space"); return { comma, found, spaceBefore, comment, hasNewline, hasNewlineAfterProp, anchor, tag, end: end2, start: start2 != null ? start2 : end2 }; } // node_modules/yaml/browser/dist/compose/util-contains-newline.js function containsNewline(key) { if (!key) return null; switch (key.type) { case "alias": case "scalar": case "double-quoted-scalar": case "single-quoted-scalar": if (key.source.includes("\n")) return true; if (key.end) { for (const st of key.end) if (st.type === "newline") return true; } return false; case "flow-collection": for (const it of key.items) { for (const st of it.start) if (st.type === "newline") return true; if (it.sep) { for (const st of it.sep) if (st.type === "newline") return true; } if (containsNewline(it.key) || containsNewline(it.value)) return true; } return false; default: return true; } } // node_modules/yaml/browser/dist/compose/util-flow-indent-check.js function flowIndentCheck(indent, fc, onError) { if ((fc == null ? void 0 : fc.type) === "flow-collection") { const end2 = fc.end[0]; if (end2.indent === indent && (end2.source === "]" || end2.source === "}") && containsNewline(fc)) { const msg = "Flow end indicator should be more indented than parent"; onError(end2, "BAD_INDENT", msg, true); } } } // node_modules/yaml/browser/dist/compose/util-map-includes.js function mapIncludes(ctx, items, search) { const { uniqueKeys } = ctx.options; if (uniqueKeys === false) return false; const isEqual = typeof uniqueKeys === "function" ? uniqueKeys : (a, b) => a === b || isScalar(a) && isScalar(b) && a.value === b.value && !(a.value === "<<" && ctx.schema.merge); return items.some((pair) => isEqual(pair.key, search)); } // node_modules/yaml/browser/dist/compose/resolve-block-map.js var startColMsg = "All mapping items must start at the same column"; function resolveBlockMap({ composeNode: composeNode2, composeEmptyNode: composeEmptyNode2 }, ctx, bm, onError, tag) { var _a, _b; const NodeClass = (_a = tag == null ? void 0 : tag.nodeClass) != null ? _a : YAMLMap; const map2 = new NodeClass(ctx.schema); if (ctx.atRoot) ctx.atRoot = false; let offset2 = bm.offset; let commentEnd = null; for (const collItem of bm.items) { const { start: start2, key, sep, value } = collItem; const keyProps = resolveProps(start2, { indicator: "explicit-key-ind", next: key != null ? key : sep == null ? void 0 : sep[0], offset: offset2, onError, startOnNewline: true }); const implicitKey = !keyProps.found; if (implicitKey) { if (key) { if (key.type === "block-seq") onError(offset2, "BLOCK_AS_IMPLICIT_KEY", "A block sequence may not be used as an implicit map key"); else if ("indent" in key && key.indent !== bm.indent) onError(offset2, "BAD_INDENT", startColMsg); } if (!keyProps.anchor && !keyProps.tag && !sep) { commentEnd = keyProps.end; if (keyProps.comment) { if (map2.comment) map2.comment += "\n" + keyProps.comment; else map2.comment = keyProps.comment; } continue; } if (keyProps.hasNewlineAfterProp || containsNewline(key)) { onError(key != null ? key : start2[start2.length - 1], "MULTILINE_IMPLICIT_KEY", "Implicit keys need to be on a single line"); } } else if (((_b = keyProps.found) == null ? void 0 : _b.indent) !== bm.indent) { onError(offset2, "BAD_INDENT", startColMsg); } const keyStart = keyProps.end; const keyNode = key ? composeNode2(ctx, key, keyProps, onError) : composeEmptyNode2(ctx, keyStart, start2, null, keyProps, onError); if (ctx.schema.compat) flowIndentCheck(bm.indent, key, onError); if (mapIncludes(ctx, map2.items, keyNode)) onError(keyStart, "DUPLICATE_KEY", "Map keys must be unique"); const valueProps = resolveProps(sep != null ? sep : [], { indicator: "map-value-ind", next: value, offset: keyNode.range[2], onError, startOnNewline: !key || key.type === "block-scalar" }); offset2 = valueProps.end; if (valueProps.found) { if (implicitKey) { if ((value == null ? void 0 : value.type) === "block-map" && !valueProps.hasNewline) onError(offset2, "BLOCK_AS_IMPLICIT_KEY", "Nested mappings are not allowed in compact mappings"); if (ctx.options.strict && keyProps.start < valueProps.found.offset - 1024) onError(keyNode.range, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit block mapping key"); } const valueNode = value ? composeNode2(ctx, value, valueProps, onError) : composeEmptyNode2(ctx, offset2, sep, null, valueProps, onError); if (ctx.schema.compat) flowIndentCheck(bm.indent, value, onError); offset2 = valueNode.range[2]; const pair = new Pair(keyNode, valueNode); if (ctx.options.keepSourceTokens) pair.srcToken = collItem; map2.items.push(pair); } else { if (implicitKey) onError(keyNode.range, "MISSING_CHAR", "Implicit map keys need to be followed by map values"); if (valueProps.comment) { if (keyNode.comment) keyNode.comment += "\n" + valueProps.comment; else keyNode.comment = valueProps.comment; } const pair = new Pair(keyNode); if (ctx.options.keepSourceTokens) pair.srcToken = collItem; map2.items.push(pair); } } if (commentEnd && commentEnd < offset2) onError(commentEnd, "IMPOSSIBLE", "Map comment with trailing content"); map2.range = [bm.offset, offset2, commentEnd != null ? commentEnd : offset2]; return map2; } // node_modules/yaml/browser/dist/compose/resolve-block-seq.js function resolveBlockSeq({ composeNode: composeNode2, composeEmptyNode: composeEmptyNode2 }, ctx, bs, onError, tag) { var _a; const NodeClass = (_a = tag == null ? void 0 : tag.nodeClass) != null ? _a : YAMLSeq; const seq2 = new NodeClass(ctx.schema); if (ctx.atRoot) ctx.atRoot = false; let offset2 = bs.offset; let commentEnd = null; for (const { start: start2, value } of bs.items) { const props = resolveProps(start2, { indicator: "seq-item-ind", next: value, offset: offset2, onError, startOnNewline: true }); if (!props.found) { if (props.anchor || props.tag || value) { if (value && value.type === "block-seq") onError(props.end, "BAD_INDENT", "All sequence items must start at the same column"); else onError(offset2, "MISSING_CHAR", "Sequence item without - indicator"); } else { commentEnd = props.end; if (props.comment) seq2.comment = props.comment; continue; } } const node = value ? composeNode2(ctx, value, props, onError) : composeEmptyNode2(ctx, props.end, start2, null, props, onError); if (ctx.schema.compat) flowIndentCheck(bs.indent, value, onError); offset2 = node.range[2]; seq2.items.push(node); } seq2.range = [bs.offset, offset2, commentEnd != null ? commentEnd : offset2]; return seq2; } // node_modules/yaml/browser/dist/compose/resolve-end.js function resolveEnd(end2, offset2, reqSpace, onError) { let comment = ""; if (end2) { let hasSpace = false; let sep = ""; for (const token of end2) { const { source, type } = token; switch (type) { case "space": hasSpace = true; break; case "comment": { if (reqSpace && !hasSpace) onError(token, "MISSING_CHAR", "Comments must be separated from other tokens by white space characters"); const cb = source.substring(1) || " "; if (!comment) comment = cb; else comment += sep + cb; sep = ""; break; } case "newline": if (comment) sep += source; hasSpace = true; break; default: onError(token, "UNEXPECTED_TOKEN", `Unexpected ${type} at node end`); } offset2 += source.length; } } return { comment, offset: offset2 }; } // node_modules/yaml/browser/dist/compose/resolve-flow-collection.js var blockMsg = "Block collections are not allowed within flow collections"; var isBlock = (token) => token && (token.type === "block-map" || token.type === "block-seq"); function resolveFlowCollection({ composeNode: composeNode2, composeEmptyNode: composeEmptyNode2 }, ctx, fc, onError, tag) { var _a, _b; const isMap2 = fc.start.source === "{"; const fcName = isMap2 ? "flow map" : "flow sequence"; const NodeClass = (_a = tag == null ? void 0 : tag.nodeClass) != null ? _a : isMap2 ? YAMLMap : YAMLSeq; const coll = new NodeClass(ctx.schema); coll.flow = true; const atRoot = ctx.atRoot; if (atRoot) ctx.atRoot = false; let offset2 = fc.offset + fc.start.source.length; for (let i = 0; i < fc.items.length; ++i) { const collItem = fc.items[i]; const { start: start2, key, sep, value } = collItem; const props = resolveProps(start2, { flow: fcName, indicator: "explicit-key-ind", next: key != null ? key : sep == null ? void 0 : sep[0], offset: offset2, onError, startOnNewline: false }); if (!props.found) { if (!props.anchor && !props.tag && !sep && !value) { if (i === 0 && props.comma) onError(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`); else if (i < fc.items.length - 1) onError(props.start, "UNEXPECTED_TOKEN", `Unexpected empty item in ${fcName}`); if (props.comment) { if (coll.comment) coll.comment += "\n" + props.comment; else coll.comment = props.comment; } offset2 = props.end; continue; } if (!isMap2 && ctx.options.strict && containsNewline(key)) onError( key, // checked by containsNewline() "MULTILINE_IMPLICIT_KEY", "Implicit keys of flow sequence pairs need to be on a single line" ); } if (i === 0) { if (props.comma) onError(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`); } else { if (!props.comma) onError(props.start, "MISSING_CHAR", `Missing , between ${fcName} items`); if (props.comment) { let prevItemComment = ""; loop: for (const st of start2) { switch (st.type) { case "comma": case "space": break; case "comment": prevItemComment = st.source.substring(1); break loop; default: break loop; } } if (prevItemComment) { let prev = coll.items[coll.items.length - 1]; if (isPair(prev)) prev = (_b = prev.value) != null ? _b : prev.key; if (prev.comment) prev.comment += "\n" + prevItemComment; else prev.comment = prevItemComment; props.comment = props.comment.substring(prevItemComment.length + 1); } } } if (!isMap2 && !sep && !props.found) { const valueNode = value ? composeNode2(ctx, value, props, onError) : composeEmptyNode2(ctx, props.end, sep, null, props, onError); coll.items.push(valueNode); offset2 = valueNode.range[2]; if (isBlock(value)) onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg); } else { const keyStart = props.end; const keyNode = key ? composeNode2(ctx, key, props, onError) : composeEmptyNode2(ctx, keyStart, start2, null, props, onError); if (isBlock(key)) onError(keyNode.range, "BLOCK_IN_FLOW", blockMsg); const valueProps = resolveProps(sep != null ? sep : [], { flow: fcName, indicator: "map-value-ind", next: value, offset: keyNode.range[2], onError, startOnNewline: false }); if (valueProps.found) { if (!isMap2 && !props.found && ctx.options.strict) { if (sep) for (const st of sep) { if (st === valueProps.found) break; if (st.type === "newline") { onError(st, "MULTILINE_IMPLICIT_KEY", "Implicit keys of flow sequence pairs need to be on a single line"); break; } } if (props.start < valueProps.found.offset - 1024) onError(valueProps.found, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit flow sequence key"); } } else if (value) { if ("source" in value && value.source && value.source[0] === ":") onError(value, "MISSING_CHAR", `Missing space after : in ${fcName}`); else onError(valueProps.start, "MISSING_CHAR", `Missing , or : between ${fcName} items`); } const valueNode = value ? composeNode2(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode2(ctx, valueProps.end, sep, null, valueProps, onError) : null; if (valueNode) { if (isBlock(value)) onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg); } else if (valueProps.comment) { if (keyNode.comment) keyNode.comment += "\n" + valueProps.comment; else keyNode.comment = valueProps.comment; } const pair = new Pair(keyNode, valueNode); if (ctx.options.keepSourceTokens) pair.srcToken = collItem; if (isMap2) { const map2 = coll; if (mapIncludes(ctx, map2.items, keyNode)) onError(keyStart, "DUPLICATE_KEY", "Map keys must be unique"); map2.items.push(pair); } else { const map2 = new YAMLMap(ctx.schema); map2.flow = true; map2.items.push(pair); coll.items.push(map2); } offset2 = valueNode ? valueNode.range[2] : valueProps.end; } } const expectedEnd = isMap2 ? "}" : "]"; const [ce, ...ee] = fc.end; let cePos = offset2; if (ce && ce.source === expectedEnd) cePos = ce.offset + ce.source.length; else { const name = fcName[0].toUpperCase() + fcName.substring(1); const msg = atRoot ? `${name} must end with a ${expectedEnd}` : `${name} in block collection must be sufficiently indented and end with a ${expectedEnd}`; onError(offset2, atRoot ? "MISSING_CHAR" : "BAD_INDENT", msg); if (ce && ce.source.length !== 1) ee.unshift(ce); } if (ee.length > 0) { const end2 = resolveEnd(ee, cePos, ctx.options.strict, onError); if (end2.comment) { if (coll.comment) coll.comment += "\n" + end2.comment; else coll.comment = end2.comment; } coll.range = [fc.offset, cePos, end2.offset]; } else { coll.range = [fc.offset, cePos, cePos]; } return coll; } // node_modules/yaml/browser/dist/compose/compose-collection.js function resolveCollection(CN2, ctx, token, onError, tagName, tag) { const coll = token.type === "block-map" ? resolveBlockMap(CN2, ctx, token, onError, tag) : token.type === "block-seq" ? resolveBlockSeq(CN2, ctx, token, onError, tag) : resolveFlowCollection(CN2, ctx, token, onError, tag); const Coll = coll.constructor; if (tagName === "!" || tagName === Coll.tagName) { coll.tag = Coll.tagName; return coll; } if (tagName) coll.tag = tagName; return coll; } function composeCollection(CN2, ctx, token, tagToken, onError) { var _a, _b; const tagName = !tagToken ? null : ctx.directives.tagName(tagToken.source, (msg) => onError(tagToken, "TAG_RESOLVE_FAILED", msg)); const expType = token.type === "block-map" ? "map" : token.type === "block-seq" ? "seq" : token.start.source === "{" ? "map" : "seq"; if (!tagToken || !tagName || tagName === "!" || tagName === YAMLMap.tagName && expType === "map" || tagName === YAMLSeq.tagName && expType === "seq" || !expType) { return resolveCollection(CN2, ctx, token, onError, tagName); } let tag = ctx.schema.tags.find((t) => t.tag === tagName && t.collection === expType); if (!tag) { const kt = ctx.schema.knownTags[tagName]; if (kt && kt.collection === expType) { ctx.schema.tags.push(Object.assign({}, kt, { default: false })); tag = kt; } else { if (kt == null ? void 0 : kt.collection) { onError(tagToken, "BAD_COLLECTION_TYPE", `${kt.tag} used for ${expType} collection, but expects ${kt.collection}`, true); } else { onError(tagToken, "TAG_RESOLVE_FAILED", `Unresolved tag: ${tagName}`, true); } return resolveCollection(CN2, ctx, token, onError, tagName); } } const coll = resolveCollection(CN2, ctx, token, onError, tagName, tag); const res = (_b = (_a = tag.resolve) == null ? void 0 : _a.call(tag, coll, (msg) => onError(tagToken, "TAG_RESOLVE_FAILED", msg), ctx.options)) != null ? _b : coll; const node = isNode(res) ? res : new Scalar(res); node.range = coll.range; node.tag = tagName; if (tag == null ? void 0 : tag.format) node.format = tag.format; return node; } // node_modules/yaml/browser/dist/compose/resolve-block-scalar.js function resolveBlockScalar(scalar, strict, onError) { const start2 = scalar.offset; const header = parseBlockScalarHeader(scalar, strict, onError); if (!header) return { value: "", type: null, comment: "", range: [start2, start2, start2] }; const type = header.mode === ">" ? Scalar.BLOCK_FOLDED : Scalar.BLOCK_LITERAL; const lines = scalar.source ? splitLines(scalar.source) : []; let chompStart = lines.length; for (let i = lines.length - 1; i >= 0; --i) { const content = lines[i][1]; if (content === "" || content === "\r") chompStart = i; else break; } if (chompStart === 0) { const value2 = header.chomp === "+" && lines.length > 0 ? "\n".repeat(Math.max(1, lines.length - 1)) : ""; let end3 = start2 + header.length; if (scalar.source) end3 += scalar.source.length; return { value: value2, type, comment: header.comment, range: [start2, end3, end3] }; } let trimIndent = scalar.indent + header.indent; let offset2 = scalar.offset + header.length; let contentStart = 0; for (let i = 0; i < chompStart; ++i) { const [indent, content] = lines[i]; if (content === "" || content === "\r") { if (header.indent === 0 && indent.length > trimIndent) trimIndent = indent.length; } else { if (indent.length < trimIndent) { const message = "Block scalars with more-indented leading empty lines must use an explicit indentation indicator"; onError(offset2 + indent.length, "MISSING_CHAR", message); } if (header.indent === 0) trimIndent = indent.length; contentStart = i; break; } offset2 += indent.length + content.length + 1; } for (let i = lines.length - 1; i >= chompStart; --i) { if (lines[i][0].length > trimIndent) chompStart = i + 1; } let value = ""; let sep = ""; let prevMoreIndented = false; for (let i = 0; i < contentStart; ++i) value += lines[i][0].slice(trimIndent) + "\n"; for (let i = contentStart; i < chompStart; ++i) { let [indent, content] = lines[i]; offset2 += indent.length + content.length + 1; const crlf = content[content.length - 1] === "\r"; if (crlf) content = content.slice(0, -1); if (content && indent.length < trimIndent) { const src = header.indent ? "explicit indentation indicator" : "first line"; const message = `Block scalar lines must not be less indented than their ${src}`; onError(offset2 - content.length - (crlf ? 2 : 1), "BAD_INDENT", message); indent = ""; } if (type === Scalar.BLOCK_LITERAL) { value += sep + indent.slice(trimIndent) + content; sep = "\n"; } else if (indent.length > trimIndent || content[0] === " ") { if (sep === " ") sep = "\n"; else if (!prevMoreIndented && sep === "\n") sep = "\n\n"; value += sep + indent.slice(trimIndent) + content; sep = "\n"; prevMoreIndented = true; } else if (content === "") { if (sep === "\n") value += "\n"; else sep = "\n"; } else { value += sep + content; sep = " "; prevMoreIndented = false; } } switch (header.chomp) { case "-": break; case "+": for (let i = chompStart; i < lines.length; ++i) value += "\n" + lines[i][0].slice(trimIndent); if (value[value.length - 1] !== "\n") value += "\n"; break; default: value += "\n"; } const end2 = start2 + header.length + scalar.source.length; return { value, type, comment: header.comment, range: [start2, end2, end2] }; } function parseBlockScalarHeader({ offset: offset2, props }, strict, onError) { if (props[0].type !== "block-scalar-header") { onError(props[0], "IMPOSSIBLE", "Block scalar header not found"); return null; } const { source } = props[0]; const mode = source[0]; let indent = 0; let chomp = ""; let error = -1; for (let i = 1; i < source.length; ++i) { const ch = source[i]; if (!chomp && (ch === "-" || ch === "+")) chomp = ch; else { const n = Number(ch); if (!indent && n) indent = n; else if (error === -1) error = offset2 + i; } } if (error !== -1) onError(error, "UNEXPECTED_TOKEN", `Block scalar header includes extra characters: ${source}`); let hasSpace = false; let comment = ""; let length = source.length; for (let i = 1; i < props.length; ++i) { const token = props[i]; switch (token.type) { case "space": hasSpace = true; case "newline": length += token.source.length; break; case "comment": if (strict && !hasSpace) { const message = "Comments must be separated from other tokens by white space characters"; onError(token, "MISSING_CHAR", message); } length += token.source.length; comment = token.source.substring(1); break; case "error": onError(token, "UNEXPECTED_TOKEN", token.message); length += token.source.length; break; default: { const message = `Unexpected token in block scalar header: ${token.type}`; onError(token, "UNEXPECTED_TOKEN", message); const ts = token.source; if (ts && typeof ts === "string") length += ts.length; } } } return { mode, indent, chomp, comment, length }; } function splitLines(source) { const split = source.split(/\n( *)/); const first = split[0]; const m = first.match(/^( *)/); const line0 = (m == null ? void 0 : m[1]) ? [m[1], first.slice(m[1].length)] : ["", first]; const lines = [line0]; for (let i = 1; i < split.length; i += 2) lines.push([split[i], split[i + 1]]); return lines; } // node_modules/yaml/browser/dist/compose/resolve-flow-scalar.js function resolveFlowScalar(scalar, strict, onError) { const { offset: offset2, type, source, end: end2 } = scalar; let _type; let value; const _onError = (rel, code, msg) => onError(offset2 + rel, code, msg); switch (type) { case "scalar": _type = Scalar.PLAIN; value = plainValue(source, _onError); break; case "single-quoted-scalar": _type = Scalar.QUOTE_SINGLE; value = singleQuotedValue(source, _onError); break; case "double-quoted-scalar": _type = Scalar.QUOTE_DOUBLE; value = doubleQuotedValue(source, _onError); break; default: onError(scalar, "UNEXPECTED_TOKEN", `Expected a flow scalar value, but found: ${type}`); return { value: "", type: null, comment: "", range: [offset2, offset2 + source.length, offset2 + source.length] }; } const valueEnd = offset2 + source.length; const re = resolveEnd(end2, valueEnd, strict, onError); return { value, type: _type, comment: re.comment, range: [offset2, valueEnd, re.offset] }; } function plainValue(source, onError) { let badChar = ""; switch (source[0]) { case " ": badChar = "a tab character"; break; case ",": badChar = "flow indicator character ,"; break; case "%": badChar = "directive indicator character %"; break; case "|": case ">": { badChar = `block scalar indicator ${source[0]}`; break; } case "@": case "`": { badChar = `reserved character ${source[0]}`; break; } } if (badChar) onError(0, "BAD_SCALAR_START", `Plain value cannot start with ${badChar}`); return foldLines(source); } function singleQuotedValue(source, onError) { if (source[source.length - 1] !== "'" || source.length === 1) onError(source.length, "MISSING_CHAR", "Missing closing 'quote"); return foldLines(source.slice(1, -1)).replace(/''/g, "'"); } function foldLines(source) { var _a; let first, line; try { first = new RegExp("(.*?)(? wsStart ? source.slice(wsStart, i + 1) : ch; } else { res += ch; } } if (source[source.length - 1] !== '"' || source.length === 1) onError(source.length, "MISSING_CHAR", 'Missing closing "quote'); return res; } function foldNewline(source, offset2) { let fold = ""; let ch = source[offset2 + 1]; while (ch === " " || ch === " " || ch === "\n" || ch === "\r") { if (ch === "\r" && source[offset2 + 2] !== "\n") break; if (ch === "\n") fold += "\n"; offset2 += 1; ch = source[offset2 + 1]; } if (!fold) fold = " "; return { fold, offset: offset2 }; } var escapeCodes = { "0": "\0", a: "\x07", b: "\b", e: "\x1B", f: "\f", n: "\n", r: "\r", t: " ", v: "\v", N: "\x85", _: "\xA0", L: "\u2028", P: "\u2029", " ": " ", '"': '"', "/": "/", "\\": "\\", " ": " " }; function parseCharCode(source, offset2, length, onError) { const cc = source.substr(offset2, length); const ok = cc.length === length && /^[0-9a-fA-F]+$/.test(cc); const code = ok ? parseInt(cc, 16) : NaN; if (isNaN(code)) { const raw = source.substr(offset2 - 2, length + 2); onError(offset2 - 2, "BAD_DQ_ESCAPE", `Invalid escape sequence ${raw}`); return raw; } return String.fromCodePoint(code); } // node_modules/yaml/browser/dist/compose/compose-scalar.js function composeScalar(ctx, token, tagToken, onError) { const { value, type, comment, range } = token.type === "block-scalar" ? resolveBlockScalar(token, ctx.options.strict, onError) : resolveFlowScalar(token, ctx.options.strict, onError); const tagName = tagToken ? ctx.directives.tagName(tagToken.source, (msg) => onError(tagToken, "TAG_RESOLVE_FAILED", msg)) : null; const tag = tagToken && tagName ? findScalarTagByName(ctx.schema, value, tagName, tagToken, onError) : token.type === "scalar" ? findScalarTagByTest(ctx, value, token, onError) : ctx.schema[SCALAR]; let scalar; try { const res = tag.resolve(value, (msg) => onError(tagToken != null ? tagToken : token, "TAG_RESOLVE_FAILED", msg), ctx.options); scalar = isScalar(res) ? res : new Scalar(res); } catch (error) { const msg = error instanceof Error ? error.message : String(error); onError(tagToken != null ? tagToken : token, "TAG_RESOLVE_FAILED", msg); scalar = new Scalar(value); } scalar.range = range; scalar.source = value; if (type) scalar.type = type; if (tagName) scalar.tag = tagName; if (tag.format) scalar.format = tag.format; if (comment) scalar.comment = comment; return scalar; } function findScalarTagByName(schema4, value, tagName, tagToken, onError) { var _a; if (tagName === "!") return schema4[SCALAR]; const matchWithTest = []; for (const tag of schema4.tags) { if (!tag.collection && tag.tag === tagName) { if (tag.default && tag.test) matchWithTest.push(tag); else return tag; } } for (const tag of matchWithTest) if ((_a = tag.test) == null ? void 0 : _a.test(value)) return tag; const kt = schema4.knownTags[tagName]; if (kt && !kt.collection) { schema4.tags.push(Object.assign({}, kt, { default: false, test: void 0 })); return kt; } onError(tagToken, "TAG_RESOLVE_FAILED", `Unresolved tag: ${tagName}`, tagName !== "tag:yaml.org,2002:str"); return schema4[SCALAR]; } function findScalarTagByTest({ directives, schema: schema4 }, value, token, onError) { var _a; const tag = schema4.tags.find((tag2) => { var _a2; return tag2.default && ((_a2 = tag2.test) == null ? void 0 : _a2.test(value)); }) || schema4[SCALAR]; if (schema4.compat) { const compat = (_a = schema4.compat.find((tag2) => { var _a2; return tag2.default && ((_a2 = tag2.test) == null ? void 0 : _a2.test(value)); })) != null ? _a : schema4[SCALAR]; if (tag.tag !== compat.tag) { const ts = directives.tagString(tag.tag); const cs = directives.tagString(compat.tag); const msg = `Value may be parsed as either ${ts} or ${cs}`; onError(token, "TAG_RESOLVE_FAILED", msg, true); } } return tag; } // node_modules/yaml/browser/dist/compose/util-empty-scalar-position.js function emptyScalarPosition(offset2, before, pos) { if (before) { if (pos === null) pos = before.length; for (let i = pos - 1; i >= 0; --i) { let st = before[i]; switch (st.type) { case "space": case "comment": case "newline": offset2 -= st.source.length; continue; } st = before[++i]; while ((st == null ? void 0 : st.type) === "space") { offset2 += st.source.length; st = before[++i]; } break; } } return offset2; } // node_modules/yaml/browser/dist/compose/compose-node.js var CN = { composeNode, composeEmptyNode }; function composeNode(ctx, token, props, onError) { const { spaceBefore, comment, anchor, tag } = props; let node; let isSrcToken = true; switch (token.type) { case "alias": node = composeAlias(ctx, token, onError); if (anchor || tag) onError(token, "ALIAS_PROPS", "An alias node must not specify any properties"); break; case "scalar": case "single-quoted-scalar": case "double-quoted-scalar": case "block-scalar": node = composeScalar(ctx, token, tag, onError); if (anchor) node.anchor = anchor.source.substring(1); break; case "block-map": case "block-seq": case "flow-collection": node = composeCollection(CN, ctx, token, tag, onError); if (anchor) node.anchor = anchor.source.substring(1); break; default: { const message = token.type === "error" ? token.message : `Unsupported token (type: ${token.type})`; onError(token, "UNEXPECTED_TOKEN", message); node = composeEmptyNode(ctx, token.offset, void 0, null, props, onError); isSrcToken = false; } } if (anchor && node.anchor === "") onError(anchor, "BAD_ALIAS", "Anchor cannot be an empty string"); if (spaceBefore) node.spaceBefore = true; if (comment) { if (token.type === "scalar" && token.source === "") node.comment = comment; else node.commentBefore = comment; } if (ctx.options.keepSourceTokens && isSrcToken) node.srcToken = token; return node; } function composeEmptyNode(ctx, offset2, before, pos, { spaceBefore, comment, anchor, tag, end: end2 }, onError) { const token = { type: "scalar", offset: emptyScalarPosition(offset2, before, pos), indent: -1, source: "" }; const node = composeScalar(ctx, token, tag, onError); if (anchor) { node.anchor = anchor.source.substring(1); if (node.anchor === "") onError(anchor, "BAD_ALIAS", "Anchor cannot be an empty string"); } if (spaceBefore) node.spaceBefore = true; if (comment) { node.comment = comment; node.range[2] = end2; } return node; } function composeAlias({ options: options2 }, { offset: offset2, source, end: end2 }, onError) { const alias = new Alias(source.substring(1)); if (alias.source === "") onError(offset2, "BAD_ALIAS", "Alias cannot be an empty string"); if (alias.source.endsWith(":")) onError(offset2 + source.length - 1, "BAD_ALIAS", "Alias ending in : is ambiguous", true); const valueEnd = offset2 + source.length; const re = resolveEnd(end2, valueEnd, options2.strict, onError); alias.range = [offset2, valueEnd, re.offset]; if (re.comment) alias.comment = re.comment; return alias; } // node_modules/yaml/browser/dist/compose/compose-doc.js function composeDoc(options2, directives, { offset: offset2, start: start2, value, end: end2 }, onError) { const opts = Object.assign({ _directives: directives }, options2); const doc = new Document(void 0, opts); const ctx = { atRoot: true, directives: doc.directives, options: doc.options, schema: doc.schema }; const props = resolveProps(start2, { indicator: "doc-start", next: value != null ? value : end2 == null ? void 0 : end2[0], offset: offset2, onError, startOnNewline: true }); if (props.found) { doc.directives.docStart = true; if (value && (value.type === "block-map" || value.type === "block-seq") && !props.hasNewline) onError(props.end, "MISSING_CHAR", "Block collection cannot start on same line with directives-end marker"); } doc.contents = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, start2, null, props, onError); const contentEnd = doc.contents.range[2]; const re = resolveEnd(end2, contentEnd, false, onError); if (re.comment) doc.comment = re.comment; doc.range = [offset2, contentEnd, re.offset]; return doc; } // node_modules/yaml/browser/dist/compose/composer.js function getErrorPos(src) { if (typeof src === "number") return [src, src + 1]; if (Array.isArray(src)) return src.length === 2 ? src : [src[0], src[1]]; const { offset: offset2, source } = src; return [offset2, offset2 + (typeof source === "string" ? source.length : 1)]; } function parsePrelude(prelude) { var _a; let comment = ""; let atComment = false; let afterEmptyLine = false; for (let i = 0; i < prelude.length; ++i) { const source = prelude[i]; switch (source[0]) { case "#": comment += (comment === "" ? "" : afterEmptyLine ? "\n\n" : "\n") + (source.substring(1) || " "); atComment = true; afterEmptyLine = false; break; case "%": if (((_a = prelude[i + 1]) == null ? void 0 : _a[0]) !== "#") i += 1; atComment = false; break; default: if (!atComment) afterEmptyLine = true; atComment = false; } } return { comment, afterEmptyLine }; } var Composer = class { constructor(options2 = {}) { this.doc = null; this.atDirectives = false; this.prelude = []; this.errors = []; this.warnings = []; this.onError = (source, code, message, warning) => { const pos = getErrorPos(source); if (warning) this.warnings.push(new YAMLWarning(pos, code, message)); else this.errors.push(new YAMLParseError(pos, code, message)); }; this.directives = new Directives({ version: options2.version || "1.2" }); this.options = options2; } decorate(doc, afterDoc) { const { comment, afterEmptyLine } = parsePrelude(this.prelude); if (comment) { const dc = doc.contents; if (afterDoc) { doc.comment = doc.comment ? `${doc.comment} ${comment}` : comment; } else if (afterEmptyLine || doc.directives.docStart || !dc) { doc.commentBefore = comment; } else if (isCollection(dc) && !dc.flow && dc.items.length > 0) { let it = dc.items[0]; if (isPair(it)) it = it.key; const cb = it.commentBefore; it.commentBefore = cb ? `${comment} ${cb}` : comment; } else { const cb = dc.commentBefore; dc.commentBefore = cb ? `${comment} ${cb}` : comment; } } if (afterDoc) { Array.prototype.push.apply(doc.errors, this.errors); Array.prototype.push.apply(doc.warnings, this.warnings); } else { doc.errors = this.errors; doc.warnings = this.warnings; } this.prelude = []; this.errors = []; this.warnings = []; } /** * Current stream status information. * * Mostly useful at the end of input for an empty stream. */ streamInfo() { return { comment: parsePrelude(this.prelude).comment, directives: this.directives, errors: this.errors, warnings: this.warnings }; } /** * Compose tokens into documents. * * @param forceDoc - If the stream contains no document, still emit a final document including any comments and directives that would be applied to a subsequent document. * @param endOffset - Should be set if `forceDoc` is also set, to set the document range end and to indicate errors correctly. */ *compose(tokens, forceDoc = false, endOffset = -1) { for (const token of tokens) yield* this.next(token); yield* this.end(forceDoc, endOffset); } /** Advance the composer by one CST token. */ *next(token) { switch (token.type) { case "directive": this.directives.add(token.source, (offset2, message, warning) => { const pos = getErrorPos(token); pos[0] += offset2; this.onError(pos, "BAD_DIRECTIVE", message, warning); }); this.prelude.push(token.source); this.atDirectives = true; break; case "document": { const doc = composeDoc(this.options, this.directives, token, this.onError); if (this.atDirectives && !doc.directives.docStart) this.onError(token, "MISSING_CHAR", "Missing directives-end/doc-start indicator line"); this.decorate(doc, false); if (this.doc) yield this.doc; this.doc = doc; this.atDirectives = false; break; } case "byte-order-mark": case "space": break; case "comment": case "newline": this.prelude.push(token.source); break; case "error": { const msg = token.source ? `${token.message}: ${JSON.stringify(token.source)}` : token.message; const error = new YAMLParseError(getErrorPos(token), "UNEXPECTED_TOKEN", msg); if (this.atDirectives || !this.doc) this.errors.push(error); else this.doc.errors.push(error); break; } case "doc-end": { if (!this.doc) { const msg = "Unexpected doc-end without preceding document"; this.errors.push(new YAMLParseError(getErrorPos(token), "UNEXPECTED_TOKEN", msg)); break; } this.doc.directives.docEnd = true; const end2 = resolveEnd(token.end, token.offset + token.source.length, this.doc.options.strict, this.onError); this.decorate(this.doc, true); if (end2.comment) { const dc = this.doc.comment; this.doc.comment = dc ? `${dc} ${end2.comment}` : end2.comment; } this.doc.range[2] = end2.offset; break; } default: this.errors.push(new YAMLParseError(getErrorPos(token), "UNEXPECTED_TOKEN", `Unsupported token ${token.type}`)); } } /** * Call at end of input to yield any remaining document. * * @param forceDoc - If the stream contains no document, still emit a final document including any comments and directives that would be applied to a subsequent document. * @param endOffset - Should be set if `forceDoc` is also set, to set the document range end and to indicate errors correctly. */ *end(forceDoc = false, endOffset = -1) { if (this.doc) { this.decorate(this.doc, true); yield this.doc; this.doc = null; } else if (forceDoc) { const opts = Object.assign({ _directives: this.directives }, this.options); const doc = new Document(void 0, opts); if (this.atDirectives) this.onError(endOffset, "MISSING_CHAR", "Missing directives-end indicator line"); doc.range = [0, endOffset, endOffset]; this.decorate(doc, false); yield doc; } } }; // node_modules/yaml/browser/dist/parse/cst-visit.js var BREAK2 = Symbol("break visit"); var SKIP2 = Symbol("skip children"); var REMOVE2 = Symbol("remove item"); function visit2(cst, visitor) { if ("type" in cst && cst.type === "document") cst = { start: cst.start, value: cst.value }; _visit(Object.freeze([]), cst, visitor); } visit2.BREAK = BREAK2; visit2.SKIP = SKIP2; visit2.REMOVE = REMOVE2; visit2.itemAtPath = (cst, path) => { let item = cst; for (const [field2, index] of path) { const tok = item == null ? void 0 : item[field2]; if (tok && "items" in tok) { item = tok.items[index]; } else return void 0; } return item; }; visit2.parentCollection = (cst, path) => { const parent = visit2.itemAtPath(cst, path.slice(0, -1)); const field2 = path[path.length - 1][0]; const coll = parent == null ? void 0 : parent[field2]; if (coll && "items" in coll) return coll; throw new Error("Parent collection not found"); }; function _visit(path, item, visitor) { let ctrl = visitor(item, path); if (typeof ctrl === "symbol") return ctrl; for (const field2 of ["key", "value"]) { const token = item[field2]; if (token && "items" in token) { for (let i = 0; i < token.items.length; ++i) { const ci = _visit(Object.freeze(path.concat([[field2, i]])), token.items[i], visitor); if (typeof ci === "number") i = ci - 1; else if (ci === BREAK2) return BREAK2; else if (ci === REMOVE2) { token.items.splice(i, 1); i -= 1; } } if (typeof ctrl === "function" && field2 === "key") ctrl = ctrl(item, path); } } return typeof ctrl === "function" ? ctrl(item, path) : ctrl; } // node_modules/yaml/browser/dist/parse/cst.js var BOM = "\uFEFF"; var DOCUMENT = ""; var FLOW_END = ""; var SCALAR2 = ""; function tokenType(source) { switch (source) { case BOM: return "byte-order-mark"; case DOCUMENT: return "doc-mode"; case FLOW_END: return "flow-error-end"; case SCALAR2: return "scalar"; case "---": return "doc-start"; case "...": return "doc-end"; case "": case "\n": case "\r\n": return "newline"; case "-": return "seq-item-ind"; case "?": return "explicit-key-ind"; case ":": return "map-value-ind"; case "{": return "flow-map-start"; case "}": return "flow-map-end"; case "[": return "flow-seq-start"; case "]": return "flow-seq-end"; case ",": return "comma"; } switch (source[0]) { case " ": case " ": return "space"; case "#": return "comment"; case "%": return "directive-line"; case "*": return "alias"; case "&": return "anchor"; case "!": return "tag"; case "'": return "single-quoted-scalar"; case '"': return "double-quoted-scalar"; case "|": case ">": return "block-scalar-header"; } return null; } // node_modules/yaml/browser/dist/parse/lexer.js function isEmpty(ch) { switch (ch) { case void 0: case " ": case "\n": case "\r": case " ": return true; default: return false; } } var hexDigits = "0123456789ABCDEFabcdef".split(""); var tagChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-#;/?:@&=+$_.!~*'()".split(""); var invalidFlowScalarChars = ",[]{}".split(""); var invalidAnchorChars = " ,[]{}\n\r ".split(""); var isNotAnchorChar = (ch) => !ch || invalidAnchorChars.includes(ch); var Lexer = class { constructor() { this.atEnd = false; this.blockScalarIndent = -1; this.blockScalarKeep = false; this.buffer = ""; this.flowKey = false; this.flowLevel = 0; this.indentNext = 0; this.indentValue = 0; this.lineEndPos = null; this.next = null; this.pos = 0; } /** * Generate YAML tokens from the `source` string. If `incomplete`, * a part of the last line may be left as a buffer for the next call. * * @returns A generator of lexical tokens */ *lex(source, incomplete = false) { var _a; if (source) { this.buffer = this.buffer ? this.buffer + source : source; this.lineEndPos = null; } this.atEnd = !incomplete; let next = (_a = this.next) != null ? _a : "stream"; while (next && (incomplete || this.hasChars(1))) next = yield* this.parseNext(next); } atLineEnd() { let i = this.pos; let ch = this.buffer[i]; while (ch === " " || ch === " ") ch = this.buffer[++i]; if (!ch || ch === "#" || ch === "\n") return true; if (ch === "\r") return this.buffer[i + 1] === "\n"; return false; } charAt(n) { return this.buffer[this.pos + n]; } continueScalar(offset2) { let ch = this.buffer[offset2]; if (this.indentNext > 0) { let indent = 0; while (ch === " ") ch = this.buffer[++indent + offset2]; if (ch === "\r") { const next = this.buffer[indent + offset2 + 1]; if (next === "\n" || !next && !this.atEnd) return offset2 + indent + 1; } return ch === "\n" || indent >= this.indentNext || !ch && !this.atEnd ? offset2 + indent : -1; } if (ch === "-" || ch === ".") { const dt = this.buffer.substr(offset2, 3); if ((dt === "---" || dt === "...") && isEmpty(this.buffer[offset2 + 3])) return -1; } return offset2; } getLine() { let end2 = this.lineEndPos; if (typeof end2 !== "number" || end2 !== -1 && end2 < this.pos) { end2 = this.buffer.indexOf("\n", this.pos); this.lineEndPos = end2; } if (end2 === -1) return this.atEnd ? this.buffer.substring(this.pos) : null; if (this.buffer[end2 - 1] === "\r") end2 -= 1; return this.buffer.substring(this.pos, end2); } hasChars(n) { return this.pos + n <= this.buffer.length; } setNext(state) { this.buffer = this.buffer.substring(this.pos); this.pos = 0; this.lineEndPos = null; this.next = state; return null; } peek(n) { return this.buffer.substr(this.pos, n); } *parseNext(next) { switch (next) { case "stream": return yield* this.parseStream(); case "line-start": return yield* this.parseLineStart(); case "block-start": return yield* this.parseBlockStart(); case "doc": return yield* this.parseDocument(); case "flow": return yield* this.parseFlowCollection(); case "quoted-scalar": return yield* this.parseQuotedScalar(); case "block-scalar": return yield* this.parseBlockScalar(); case "plain-scalar": return yield* this.parsePlainScalar(); } } *parseStream() { let line = this.getLine(); if (line === null) return this.setNext("stream"); if (line[0] === BOM) { yield* this.pushCount(1); line = line.substring(1); } if (line[0] === "%") { let dirEnd = line.length; const cs = line.indexOf("#"); if (cs !== -1) { const ch = line[cs - 1]; if (ch === " " || ch === " ") dirEnd = cs - 1; } while (true) { const ch = line[dirEnd - 1]; if (ch === " " || ch === " ") dirEnd -= 1; else break; } const n = (yield* this.pushCount(dirEnd)) + (yield* this.pushSpaces(true)); yield* this.pushCount(line.length - n); this.pushNewline(); return "stream"; } if (this.atLineEnd()) { const sp = yield* this.pushSpaces(true); yield* this.pushCount(line.length - sp); yield* this.pushNewline(); return "stream"; } yield DOCUMENT; return yield* this.parseLineStart(); } *parseLineStart() { const ch = this.charAt(0); if (!ch && !this.atEnd) return this.setNext("line-start"); if (ch === "-" || ch === ".") { if (!this.atEnd && !this.hasChars(4)) return this.setNext("line-start"); const s = this.peek(3); if (s === "---" && isEmpty(this.charAt(3))) { yield* this.pushCount(3); this.indentValue = 0; this.indentNext = 0; return "doc"; } else if (s === "..." && isEmpty(this.charAt(3))) { yield* this.pushCount(3); return "stream"; } } this.indentValue = yield* this.pushSpaces(false); if (this.indentNext > this.indentValue && !isEmpty(this.charAt(1))) this.indentNext = this.indentValue; return yield* this.parseBlockStart(); } *parseBlockStart() { const [ch0, ch1] = this.peek(2); if (!ch1 && !this.atEnd) return this.setNext("block-start"); if ((ch0 === "-" || ch0 === "?" || ch0 === ":") && isEmpty(ch1)) { const n = (yield* this.pushCount(1)) + (yield* this.pushSpaces(true)); this.indentNext = this.indentValue + 1; this.indentValue += n; return yield* this.parseBlockStart(); } return "doc"; } *parseDocument() { yield* this.pushSpaces(true); const line = this.getLine(); if (line === null) return this.setNext("doc"); let n = yield* this.pushIndicators(); switch (line[n]) { case "#": yield* this.pushCount(line.length - n); case void 0: yield* this.pushNewline(); return yield* this.parseLineStart(); case "{": case "[": yield* this.pushCount(1); this.flowKey = false; this.flowLevel = 1; return "flow"; case "}": case "]": yield* this.pushCount(1); return "doc"; case "*": yield* this.pushUntil(isNotAnchorChar); return "doc"; case '"': case "'": return yield* this.parseQuotedScalar(); case "|": case ">": n += yield* this.parseBlockScalarHeader(); n += yield* this.pushSpaces(true); yield* this.pushCount(line.length - n); yield* this.pushNewline(); return yield* this.parseBlockScalar(); default: return yield* this.parsePlainScalar(); } } *parseFlowCollection() { let nl, sp; let indent = -1; do { nl = yield* this.pushNewline(); if (nl > 0) { sp = yield* this.pushSpaces(false); this.indentValue = indent = sp; } else { sp = 0; } sp += yield* this.pushSpaces(true); } while (nl + sp > 0); const line = this.getLine(); if (line === null) return this.setNext("flow"); if (indent !== -1 && indent < this.indentNext && line[0] !== "#" || indent === 0 && (line.startsWith("---") || line.startsWith("...")) && isEmpty(line[3])) { const atFlowEndMarker = indent === this.indentNext - 1 && this.flowLevel === 1 && (line[0] === "]" || line[0] === "}"); if (!atFlowEndMarker) { this.flowLevel = 0; yield FLOW_END; return yield* this.parseLineStart(); } } let n = 0; while (line[n] === ",") { n += yield* this.pushCount(1); n += yield* this.pushSpaces(true); this.flowKey = false; } n += yield* this.pushIndicators(); switch (line[n]) { case void 0: return "flow"; case "#": yield* this.pushCount(line.length - n); return "flow"; case "{": case "[": yield* this.pushCount(1); this.flowKey = false; this.flowLevel += 1; return "flow"; case "}": case "]": yield* this.pushCount(1); this.flowKey = true; this.flowLevel -= 1; return this.flowLevel ? "flow" : "doc"; case "*": yield* this.pushUntil(isNotAnchorChar); return "flow"; case '"': case "'": this.flowKey = true; return yield* this.parseQuotedScalar(); case ":": { const next = this.charAt(1); if (this.flowKey || isEmpty(next) || next === ",") { this.flowKey = false; yield* this.pushCount(1); yield* this.pushSpaces(true); return "flow"; } } default: this.flowKey = false; return yield* this.parsePlainScalar(); } } *parseQuotedScalar() { const quote = this.charAt(0); let end2 = this.buffer.indexOf(quote, this.pos + 1); if (quote === "'") { while (end2 !== -1 && this.buffer[end2 + 1] === "'") end2 = this.buffer.indexOf("'", end2 + 2); } else { while (end2 !== -1) { let n = 0; while (this.buffer[end2 - 1 - n] === "\\") n += 1; if (n % 2 === 0) break; end2 = this.buffer.indexOf('"', end2 + 1); } } const qb = this.buffer.substring(0, end2); let nl = qb.indexOf("\n", this.pos); if (nl !== -1) { while (nl !== -1) { const cs = this.continueScalar(nl + 1); if (cs === -1) break; nl = qb.indexOf("\n", cs); } if (nl !== -1) { end2 = nl - (qb[nl - 1] === "\r" ? 2 : 1); } } if (end2 === -1) { if (!this.atEnd) return this.setNext("quoted-scalar"); end2 = this.buffer.length; } yield* this.pushToIndex(end2 + 1, false); return this.flowLevel ? "flow" : "doc"; } *parseBlockScalarHeader() { this.blockScalarIndent = -1; this.blockScalarKeep = false; let i = this.pos; while (true) { const ch = this.buffer[++i]; if (ch === "+") this.blockScalarKeep = true; else if (ch > "0" && ch <= "9") this.blockScalarIndent = Number(ch) - 1; else if (ch !== "-") break; } return yield* this.pushUntil((ch) => isEmpty(ch) || ch === "#"); } *parseBlockScalar() { let nl = this.pos - 1; let indent = 0; let ch; loop: for (let i = this.pos; ch = this.buffer[i]; ++i) { switch (ch) { case " ": indent += 1; break; case "\n": nl = i; indent = 0; break; case "\r": { const next = this.buffer[i + 1]; if (!next && !this.atEnd) return this.setNext("block-scalar"); if (next === "\n") break; } default: break loop; } } if (!ch && !this.atEnd) return this.setNext("block-scalar"); if (indent >= this.indentNext) { if (this.blockScalarIndent === -1) this.indentNext = indent; else this.indentNext += this.blockScalarIndent; do { const cs = this.continueScalar(nl + 1); if (cs === -1) break; nl = this.buffer.indexOf("\n", cs); } while (nl !== -1); if (nl === -1) { if (!this.atEnd) return this.setNext("block-scalar"); nl = this.buffer.length; } } if (!this.blockScalarKeep) { do { let i = nl - 1; let ch2 = this.buffer[i]; if (ch2 === "\r") ch2 = this.buffer[--i]; const lastChar = i; while (ch2 === " " || ch2 === " ") ch2 = this.buffer[--i]; if (ch2 === "\n" && i >= this.pos && i + 1 + indent > lastChar) nl = i; else break; } while (true); } yield SCALAR2; yield* this.pushToIndex(nl + 1, true); return yield* this.parseLineStart(); } *parsePlainScalar() { const inFlow = this.flowLevel > 0; let end2 = this.pos - 1; let i = this.pos - 1; let ch; while (ch = this.buffer[++i]) { if (ch === ":") { const next = this.buffer[i + 1]; if (isEmpty(next) || inFlow && next === ",") break; end2 = i; } else if (isEmpty(ch)) { let next = this.buffer[i + 1]; if (ch === "\r") { if (next === "\n") { i += 1; ch = "\n"; next = this.buffer[i + 1]; } else end2 = i; } if (next === "#" || inFlow && invalidFlowScalarChars.includes(next)) break; if (ch === "\n") { const cs = this.continueScalar(i + 1); if (cs === -1) break; i = Math.max(i, cs - 2); } } else { if (inFlow && invalidFlowScalarChars.includes(ch)) break; end2 = i; } } if (!ch && !this.atEnd) return this.setNext("plain-scalar"); yield SCALAR2; yield* this.pushToIndex(end2 + 1, true); return inFlow ? "flow" : "doc"; } *pushCount(n) { if (n > 0) { yield this.buffer.substr(this.pos, n); this.pos += n; return n; } return 0; } *pushToIndex(i, allowEmpty) { const s = this.buffer.slice(this.pos, i); if (s) { yield s; this.pos += s.length; return s.length; } else if (allowEmpty) yield ""; return 0; } *pushIndicators() { switch (this.charAt(0)) { case "!": return (yield* this.pushTag()) + (yield* this.pushSpaces(true)) + (yield* this.pushIndicators()); case "&": return (yield* this.pushUntil(isNotAnchorChar)) + (yield* this.pushSpaces(true)) + (yield* this.pushIndicators()); case "-": case "?": case ":": { const inFlow = this.flowLevel > 0; const ch1 = this.charAt(1); if (isEmpty(ch1) || inFlow && invalidFlowScalarChars.includes(ch1)) { if (!inFlow) this.indentNext = this.indentValue + 1; else if (this.flowKey) this.flowKey = false; return (yield* this.pushCount(1)) + (yield* this.pushSpaces(true)) + (yield* this.pushIndicators()); } } } return 0; } *pushTag() { if (this.charAt(1) === "<") { let i = this.pos + 2; let ch = this.buffer[i]; while (!isEmpty(ch) && ch !== ">") ch = this.buffer[++i]; return yield* this.pushToIndex(ch === ">" ? i + 1 : i, false); } else { let i = this.pos + 1; let ch = this.buffer[i]; while (ch) { if (tagChars.includes(ch)) ch = this.buffer[++i]; else if (ch === "%" && hexDigits.includes(this.buffer[i + 1]) && hexDigits.includes(this.buffer[i + 2])) { ch = this.buffer[i += 3]; } else break; } return yield* this.pushToIndex(i, false); } } *pushNewline() { const ch = this.buffer[this.pos]; if (ch === "\n") return yield* this.pushCount(1); else if (ch === "\r" && this.charAt(1) === "\n") return yield* this.pushCount(2); else return 0; } *pushSpaces(allowTabs) { let i = this.pos - 1; let ch; do { ch = this.buffer[++i]; } while (ch === " " || allowTabs && ch === " "); const n = i - this.pos; if (n > 0) { yield this.buffer.substr(this.pos, n); this.pos = i; } return n; } *pushUntil(test) { let i = this.pos; let ch = this.buffer[i]; while (!test(ch)) ch = this.buffer[++i]; return yield* this.pushToIndex(i, false); } }; // node_modules/yaml/browser/dist/parse/line-counter.js var LineCounter = class { constructor() { this.lineStarts = []; this.addNewLine = (offset2) => this.lineStarts.push(offset2); this.linePos = (offset2) => { let low = 0; let high = this.lineStarts.length; while (low < high) { const mid = low + high >> 1; if (this.lineStarts[mid] < offset2) low = mid + 1; else high = mid; } if (this.lineStarts[low] === offset2) return { line: low + 1, col: 1 }; if (low === 0) return { line: 0, col: offset2 }; const start2 = this.lineStarts[low - 1]; return { line: low, col: offset2 - start2 + 1 }; }; } }; // node_modules/yaml/browser/dist/parse/parser.js function includesToken(list, type) { for (let i = 0; i < list.length; ++i) if (list[i].type === type) return true; return false; } function findNonEmptyIndex(list) { for (let i = 0; i < list.length; ++i) { switch (list[i].type) { case "space": case "comment": case "newline": break; default: return i; } } return -1; } function isFlowToken(token) { switch (token == null ? void 0 : token.type) { case "alias": case "scalar": case "single-quoted-scalar": case "double-quoted-scalar": case "flow-collection": return true; default: return false; } } function getPrevProps(parent) { var _a; switch (parent.type) { case "document": return parent.start; case "block-map": { const it = parent.items[parent.items.length - 1]; return (_a = it.sep) != null ? _a : it.start; } case "block-seq": return parent.items[parent.items.length - 1].start; default: return []; } } function getFirstKeyStartProps(prev) { var _a; if (prev.length === 0) return []; let i = prev.length; loop: while (--i >= 0) { switch (prev[i].type) { case "doc-start": case "explicit-key-ind": case "map-value-ind": case "seq-item-ind": case "newline": break loop; } } while (((_a = prev[++i]) == null ? void 0 : _a.type) === "space") { } return prev.splice(i, prev.length); } function fixFlowSeqItems(fc) { if (fc.start.type === "flow-seq-start") { for (const it of fc.items) { if (it.sep && !it.value && !includesToken(it.start, "explicit-key-ind") && !includesToken(it.sep, "map-value-ind")) { if (it.key) it.value = it.key; delete it.key; if (isFlowToken(it.value)) { if (it.value.end) Array.prototype.push.apply(it.value.end, it.sep); else it.value.end = it.sep; } else Array.prototype.push.apply(it.start, it.sep); delete it.sep; } } } } var Parser = class { /** * @param onNewLine - If defined, called separately with the start position of * each new line (in `parse()`, including the start of input). */ constructor(onNewLine) { this.atNewLine = true; this.atScalar = false; this.indent = 0; this.offset = 0; this.onKeyLine = false; this.stack = []; this.source = ""; this.type = ""; this.lexer = new Lexer(); this.onNewLine = onNewLine; } /** * Parse `source` as a YAML stream. * If `incomplete`, a part of the last line may be left as a buffer for the next call. * * Errors are not thrown, but yielded as `{ type: 'error', message }` tokens. * * @returns A generator of tokens representing each directive, document, and other structure. */ *parse(source, incomplete = false) { if (this.onNewLine && this.offset === 0) this.onNewLine(0); for (const lexeme of this.lexer.lex(source, incomplete)) yield* this.next(lexeme); if (!incomplete) yield* this.end(); } /** * Advance the parser by the `source` of one lexical token. */ *next(source) { this.source = source; if (this.atScalar) { this.atScalar = false; yield* this.step(); this.offset += source.length; return; } const type = tokenType(source); if (!type) { const message = `Not a YAML token: ${source}`; yield* this.pop({ type: "error", offset: this.offset, message, source }); this.offset += source.length; } else if (type === "scalar") { this.atNewLine = false; this.atScalar = true; this.type = "scalar"; } else { this.type = type; yield* this.step(); switch (type) { case "newline": this.atNewLine = true; this.indent = 0; if (this.onNewLine) this.onNewLine(this.offset + source.length); break; case "space": if (this.atNewLine && source[0] === " ") this.indent += source.length; break; case "explicit-key-ind": case "map-value-ind": case "seq-item-ind": if (this.atNewLine) this.indent += source.length; break; case "doc-mode": case "flow-error-end": return; default: this.atNewLine = false; } this.offset += source.length; } } /** Call at end of input to push out any remaining constructions */ *end() { while (this.stack.length > 0) yield* this.pop(); } get sourceToken() { const st = { type: this.type, offset: this.offset, indent: this.indent, source: this.source }; return st; } *step() { const top2 = this.peek(1); if (this.type === "doc-end" && (!top2 || top2.type !== "doc-end")) { while (this.stack.length > 0) yield* this.pop(); this.stack.push({ type: "doc-end", offset: this.offset, source: this.source }); return; } if (!top2) return yield* this.stream(); switch (top2.type) { case "document": return yield* this.document(top2); case "alias": case "scalar": case "single-quoted-scalar": case "double-quoted-scalar": return yield* this.scalar(top2); case "block-scalar": return yield* this.blockScalar(top2); case "block-map": return yield* this.blockMap(top2); case "block-seq": return yield* this.blockSequence(top2); case "flow-collection": return yield* this.flowCollection(top2); case "doc-end": return yield* this.documentEnd(top2); } yield* this.pop(); } peek(n) { return this.stack[this.stack.length - n]; } *pop(error) { const token = error != null ? error : this.stack.pop(); if (!token) { const message = "Tried to pop an empty stack"; yield { type: "error", offset: this.offset, source: "", message }; } else if (this.stack.length === 0) { yield token; } else { const top2 = this.peek(1); if (token.type === "block-scalar") { token.indent = "indent" in top2 ? top2.indent : 0; } else if (token.type === "flow-collection" && top2.type === "document") { token.indent = 0; } if (token.type === "flow-collection") fixFlowSeqItems(token); switch (top2.type) { case "document": top2.value = token; break; case "block-scalar": top2.props.push(token); break; case "block-map": { const it = top2.items[top2.items.length - 1]; if (it.value) { top2.items.push({ start: [], key: token, sep: [] }); this.onKeyLine = true; return; } else if (it.sep) { it.value = token; } else { Object.assign(it, { key: token, sep: [] }); this.onKeyLine = !includesToken(it.start, "explicit-key-ind"); return; } break; } case "block-seq": { const it = top2.items[top2.items.length - 1]; if (it.value) top2.items.push({ start: [], value: token }); else it.value = token; break; } case "flow-collection": { const it = top2.items[top2.items.length - 1]; if (!it || it.value) top2.items.push({ start: [], key: token, sep: [] }); else if (it.sep) it.value = token; else Object.assign(it, { key: token, sep: [] }); return; } default: yield* this.pop(); yield* this.pop(token); } if ((top2.type === "document" || top2.type === "block-map" || top2.type === "block-seq") && (token.type === "block-map" || token.type === "block-seq")) { const last = token.items[token.items.length - 1]; if (last && !last.sep && !last.value && last.start.length > 0 && findNonEmptyIndex(last.start) === -1 && (token.indent === 0 || last.start.every((st) => st.type !== "comment" || st.indent < token.indent))) { if (top2.type === "document") top2.end = last.start; else top2.items.push({ start: last.start }); token.items.splice(-1, 1); } } } } *stream() { switch (this.type) { case "directive-line": yield { type: "directive", offset: this.offset, source: this.source }; return; case "byte-order-mark": case "space": case "comment": case "newline": yield this.sourceToken; return; case "doc-mode": case "doc-start": { const doc = { type: "document", offset: this.offset, start: [] }; if (this.type === "doc-start") doc.start.push(this.sourceToken); this.stack.push(doc); return; } } yield { type: "error", offset: this.offset, message: `Unexpected ${this.type} token in YAML stream`, source: this.source }; } *document(doc) { if (doc.value) return yield* this.lineEnd(doc); switch (this.type) { case "doc-start": { if (findNonEmptyIndex(doc.start) !== -1) { yield* this.pop(); yield* this.step(); } else doc.start.push(this.sourceToken); return; } case "anchor": case "tag": case "space": case "comment": case "newline": doc.start.push(this.sourceToken); return; } const bv = this.startBlockValue(doc); if (bv) this.stack.push(bv); else { yield { type: "error", offset: this.offset, message: `Unexpected ${this.type} token in YAML document`, source: this.source }; } } *scalar(scalar) { if (this.type === "map-value-ind") { const prev = getPrevProps(this.peek(2)); const start2 = getFirstKeyStartProps(prev); let sep; if (scalar.end) { sep = scalar.end; sep.push(this.sourceToken); delete scalar.end; } else sep = [this.sourceToken]; const map2 = { type: "block-map", offset: scalar.offset, indent: scalar.indent, items: [{ start: start2, key: scalar, sep }] }; this.onKeyLine = true; this.stack[this.stack.length - 1] = map2; } else yield* this.lineEnd(scalar); } *blockScalar(scalar) { switch (this.type) { case "space": case "comment": case "newline": scalar.props.push(this.sourceToken); return; case "scalar": scalar.source = this.source; this.atNewLine = true; this.indent = 0; if (this.onNewLine) { let nl = this.source.indexOf("\n") + 1; while (nl !== 0) { this.onNewLine(this.offset + nl); nl = this.source.indexOf("\n", nl) + 1; } } yield* this.pop(); break; default: yield* this.pop(); yield* this.step(); } } *blockMap(map2) { var _a; const it = map2.items[map2.items.length - 1]; switch (this.type) { case "newline": this.onKeyLine = false; if (it.value) { const end2 = "end" in it.value ? it.value.end : void 0; const last = Array.isArray(end2) ? end2[end2.length - 1] : void 0; if ((last == null ? void 0 : last.type) === "comment") end2 == null ? void 0 : end2.push(this.sourceToken); else map2.items.push({ start: [this.sourceToken] }); } else if (it.sep) { it.sep.push(this.sourceToken); } else { it.start.push(this.sourceToken); } return; case "space": case "comment": if (it.value) { map2.items.push({ start: [this.sourceToken] }); } else if (it.sep) { it.sep.push(this.sourceToken); } else { if (this.atIndentedComment(it.start, map2.indent)) { const prev = map2.items[map2.items.length - 2]; const end2 = (_a = prev == null ? void 0 : prev.value) == null ? void 0 : _a.end; if (Array.isArray(end2)) { Array.prototype.push.apply(end2, it.start); end2.push(this.sourceToken); map2.items.pop(); return; } } it.start.push(this.sourceToken); } return; } if (this.indent >= map2.indent) { const atNextItem = !this.onKeyLine && this.indent === map2.indent && it.sep; let start2 = []; if (atNextItem && it.sep && !it.value) { const nl = []; for (let i = 0; i < it.sep.length; ++i) { const st = it.sep[i]; switch (st.type) { case "newline": nl.push(i); break; case "space": break; case "comment": if (st.indent > map2.indent) nl.length = 0; break; default: nl.length = 0; } } if (nl.length >= 2) start2 = it.sep.splice(nl[1]); } switch (this.type) { case "anchor": case "tag": if (atNextItem || it.value) { start2.push(this.sourceToken); map2.items.push({ start: start2 }); this.onKeyLine = true; } else if (it.sep) { it.sep.push(this.sourceToken); } else { it.start.push(this.sourceToken); } return; case "explicit-key-ind": if (!it.sep && !includesToken(it.start, "explicit-key-ind")) { it.start.push(this.sourceToken); } else if (atNextItem || it.value) { start2.push(this.sourceToken); map2.items.push({ start: start2 }); } else { this.stack.push({ type: "block-map", offset: this.offset, indent: this.indent, items: [{ start: [this.sourceToken] }] }); } this.onKeyLine = true; return; case "map-value-ind": if (includesToken(it.start, "explicit-key-ind")) { if (!it.sep) { if (includesToken(it.start, "newline")) { Object.assign(it, { key: null, sep: [this.sourceToken] }); } else { const start3 = getFirstKeyStartProps(it.start); this.stack.push({ type: "block-map", offset: this.offset, indent: this.indent, items: [{ start: start3, key: null, sep: [this.sourceToken] }] }); } } else if (it.value) { map2.items.push({ start: [], key: null, sep: [this.sourceToken] }); } else if (includesToken(it.sep, "map-value-ind")) { this.stack.push({ type: "block-map", offset: this.offset, indent: this.indent, items: [{ start: start2, key: null, sep: [this.sourceToken] }] }); } else if (isFlowToken(it.key) && !includesToken(it.sep, "newline")) { const start3 = getFirstKeyStartProps(it.start); const key = it.key; const sep = it.sep; sep.push(this.sourceToken); delete it.key, delete it.sep; this.stack.push({ type: "block-map", offset: this.offset, indent: this.indent, items: [{ start: start3, key, sep }] }); } else if (start2.length > 0) { it.sep = it.sep.concat(start2, this.sourceToken); } else { it.sep.push(this.sourceToken); } } else { if (!it.sep) { Object.assign(it, { key: null, sep: [this.sourceToken] }); } else if (it.value || atNextItem) { map2.items.push({ start: start2, key: null, sep: [this.sourceToken] }); } else if (includesToken(it.sep, "map-value-ind")) { this.stack.push({ type: "block-map", offset: this.offset, indent: this.indent, items: [{ start: [], key: null, sep: [this.sourceToken] }] }); } else { it.sep.push(this.sourceToken); } } this.onKeyLine = true; return; case "alias": case "scalar": case "single-quoted-scalar": case "double-quoted-scalar": { const fs = this.flowScalar(this.type); if (atNextItem || it.value) { map2.items.push({ start: start2, key: fs, sep: [] }); this.onKeyLine = true; } else if (it.sep) { this.stack.push(fs); } else { Object.assign(it, { key: fs, sep: [] }); this.onKeyLine = true; } return; } default: { const bv = this.startBlockValue(map2); if (bv) { if (atNextItem && bv.type !== "block-seq" && includesToken(it.start, "explicit-key-ind")) { map2.items.push({ start: start2 }); } this.stack.push(bv); return; } } } } yield* this.pop(); yield* this.step(); } *blockSequence(seq2) { var _a; const it = seq2.items[seq2.items.length - 1]; switch (this.type) { case "newline": if (it.value) { const end2 = "end" in it.value ? it.value.end : void 0; const last = Array.isArray(end2) ? end2[end2.length - 1] : void 0; if ((last == null ? void 0 : last.type) === "comment") end2 == null ? void 0 : end2.push(this.sourceToken); else seq2.items.push({ start: [this.sourceToken] }); } else it.start.push(this.sourceToken); return; case "space": case "comment": if (it.value) seq2.items.push({ start: [this.sourceToken] }); else { if (this.atIndentedComment(it.start, seq2.indent)) { const prev = seq2.items[seq2.items.length - 2]; const end2 = (_a = prev == null ? void 0 : prev.value) == null ? void 0 : _a.end; if (Array.isArray(end2)) { Array.prototype.push.apply(end2, it.start); end2.push(this.sourceToken); seq2.items.pop(); return; } } it.start.push(this.sourceToken); } return; case "anchor": case "tag": if (it.value || this.indent <= seq2.indent) break; it.start.push(this.sourceToken); return; case "seq-item-ind": if (this.indent !== seq2.indent) break; if (it.value || includesToken(it.start, "seq-item-ind")) seq2.items.push({ start: [this.sourceToken] }); else it.start.push(this.sourceToken); return; } if (this.indent > seq2.indent) { const bv = this.startBlockValue(seq2); if (bv) { this.stack.push(bv); return; } } yield* this.pop(); yield* this.step(); } *flowCollection(fc) { const it = fc.items[fc.items.length - 1]; if (this.type === "flow-error-end") { let top2; do { yield* this.pop(); top2 = this.peek(1); } while (top2 && top2.type === "flow-collection"); } else if (fc.end.length === 0) { switch (this.type) { case "comma": case "explicit-key-ind": if (!it || it.sep) fc.items.push({ start: [this.sourceToken] }); else it.start.push(this.sourceToken); return; case "map-value-ind": if (!it || it.value) fc.items.push({ start: [], key: null, sep: [this.sourceToken] }); else if (it.sep) it.sep.push(this.sourceToken); else Object.assign(it, { key: null, sep: [this.sourceToken] }); return; case "space": case "comment": case "newline": case "anchor": case "tag": if (!it || it.value) fc.items.push({ start: [this.sourceToken] }); else if (it.sep) it.sep.push(this.sourceToken); else it.start.push(this.sourceToken); return; case "alias": case "scalar": case "single-quoted-scalar": case "double-quoted-scalar": { const fs = this.flowScalar(this.type); if (!it || it.value) fc.items.push({ start: [], key: fs, sep: [] }); else if (it.sep) this.stack.push(fs); else Object.assign(it, { key: fs, sep: [] }); return; } case "flow-map-end": case "flow-seq-end": fc.end.push(this.sourceToken); return; } const bv = this.startBlockValue(fc); if (bv) this.stack.push(bv); else { yield* this.pop(); yield* this.step(); } } else { const parent = this.peek(2); if (parent.type === "block-map" && (this.type === "map-value-ind" && parent.indent === fc.indent || this.type === "newline" && !parent.items[parent.items.length - 1].sep)) { yield* this.pop(); yield* this.step(); } else if (this.type === "map-value-ind" && parent.type !== "flow-collection") { const prev = getPrevProps(parent); const start2 = getFirstKeyStartProps(prev); fixFlowSeqItems(fc); const sep = fc.end.splice(1, fc.end.length); sep.push(this.sourceToken); const map2 = { type: "block-map", offset: fc.offset, indent: fc.indent, items: [{ start: start2, key: fc, sep }] }; this.onKeyLine = true; this.stack[this.stack.length - 1] = map2; } else { yield* this.lineEnd(fc); } } } flowScalar(type) { if (this.onNewLine) { let nl = this.source.indexOf("\n") + 1; while (nl !== 0) { this.onNewLine(this.offset + nl); nl = this.source.indexOf("\n", nl) + 1; } } return { type, offset: this.offset, indent: this.indent, source: this.source }; } startBlockValue(parent) { switch (this.type) { case "alias": case "scalar": case "single-quoted-scalar": case "double-quoted-scalar": return this.flowScalar(this.type); case "block-scalar-header": return { type: "block-scalar", offset: this.offset, indent: this.indent, props: [this.sourceToken], source: "" }; case "flow-map-start": case "flow-seq-start": return { type: "flow-collection", offset: this.offset, indent: this.indent, start: this.sourceToken, items: [], end: [] }; case "seq-item-ind": return { type: "block-seq", offset: this.offset, indent: this.indent, items: [{ start: [this.sourceToken] }] }; case "explicit-key-ind": { this.onKeyLine = true; const prev = getPrevProps(parent); const start2 = getFirstKeyStartProps(prev); start2.push(this.sourceToken); return { type: "block-map", offset: this.offset, indent: this.indent, items: [{ start: start2 }] }; } case "map-value-ind": { this.onKeyLine = true; const prev = getPrevProps(parent); const start2 = getFirstKeyStartProps(prev); return { type: "block-map", offset: this.offset, indent: this.indent, items: [{ start: start2, key: null, sep: [this.sourceToken] }] }; } } return null; } atIndentedComment(start2, indent) { if (this.type !== "comment") return false; if (this.indent <= indent) return false; return start2.every((st) => st.type === "newline" || st.type === "space"); } *documentEnd(docEnd) { if (this.type !== "doc-mode") { if (docEnd.end) docEnd.end.push(this.sourceToken); else docEnd.end = [this.sourceToken]; if (this.type === "newline") yield* this.pop(); } } *lineEnd(token) { switch (this.type) { case "comma": case "doc-start": case "doc-end": case "flow-seq-end": case "flow-map-end": case "map-value-ind": yield* this.pop(); yield* this.step(); break; case "newline": this.onKeyLine = false; case "space": case "comment": default: if (token.end) token.end.push(this.sourceToken); else token.end = [this.sourceToken]; if (this.type === "newline") yield* this.pop(); } } }; // node_modules/yaml/browser/dist/public-api.js function parseOptions(options2) { const prettyErrors = options2.prettyErrors !== false; const lineCounter = options2.lineCounter || prettyErrors && new LineCounter() || null; return { lineCounter, prettyErrors }; } function parseDocument(source, options2 = {}) { const { lineCounter, prettyErrors } = parseOptions(options2); const parser2 = new Parser(lineCounter == null ? void 0 : lineCounter.addNewLine); const composer = new Composer(options2); let doc = null; for (const _doc of composer.compose(parser2.parse(source), true, source.length)) { if (!doc) doc = _doc; else if (doc.options.logLevel !== "silent") { doc.errors.push(new YAMLParseError(_doc.range.slice(0, 2), "MULTIPLE_DOCS", "Source contains multiple documents; please use YAML.parseAllDocuments()")); break; } } if (prettyErrors && lineCounter) { doc.errors.forEach(prettifyError(source, lineCounter)); doc.warnings.forEach(prettifyError(source, lineCounter)); } return doc; } function parse(src, reviver, options2) { let _reviver = void 0; if (typeof reviver === "function") { _reviver = reviver; } else if (options2 === void 0 && reviver && typeof reviver === "object") { options2 = reviver; } const doc = parseDocument(src, options2); if (!doc) return null; doc.warnings.forEach((warning) => warn(doc.options.logLevel, warning)); if (doc.errors.length > 0) { if (doc.options.logLevel !== "silent") throw doc.errors[0]; else doc.errors = []; } return doc.toJS(Object.assign({ reviver: _reviver }, options2)); } function stringify3(value, replacer, options2) { var _a; let _replacer = null; if (typeof replacer === "function" || Array.isArray(replacer)) { _replacer = replacer; } else if (options2 === void 0 && replacer) { options2 = replacer; } if (typeof options2 === "string") options2 = options2.length; if (typeof options2 === "number") { const indent = Math.round(options2); options2 = indent < 1 ? void 0 : indent > 8 ? { indent: 8 } : { indent }; } if (value === void 0) { const { keepUndefined } = (_a = options2 != null ? options2 : replacer) != null ? _a : {}; if (!keepUndefined) return void 0; } return new Document(value, _replacer, options2).toString(options2); } // src/fields/models/YAML.ts var import_obsidian28 = require("obsidian"); var Base22 = class { constructor() { this.type = "YAML"; this.tagName = "yaml"; this.icon = "file-json-2"; this.tooltip = "Accepts a YAML object"; this.colorClass = "file"; } }; var DefaultOptions26 = DefaultOptions24; function settingsModal26(Base25) { return settingsModal24(Base25); } function valueModal20(managedField, plugin) { const base = valueModal18(managedField, plugin); return class ValueModal extends base { dumpValue(value) { return dumpValue(value); } getExtraExtensions() { const yaml2 = new import_language3.LanguageSupport(import_language3.StreamLanguage.define(yaml)); const yamlLinter = (0, import_lint4.linter)((view) => { let diagnostics = []; try { parse(view.state.doc.toString()); } catch (e) { var loc = e.mark; var from = loc ? Math.min(loc.position, view.state.doc.length) : 0; var to = from; var severity = "error"; diagnostics.push({ from, to, message: e.message, severity }); } return diagnostics; }); return [yaml2, yamlLinter]; } loadValue(value) { try { return parse(value.split("\\n").join("\n") || null); } catch (e) { return value; } } }; } function valueString25(managedField) { const valueString29 = `${stringify3(managedField.value, { lineWidth: 50 }) || ""}`; return `${valueString29.slice(0, 50)}${valueString29.length > 50 ? "..." : ""}`; } function displayValue25(managedField, container, onClicked) { container.setText(valueString25(managedField)); } function createDvField19(managedField, dv, p, fieldContainer, attrs = {}) { var _a, _b; attrs.cls = "value-container"; const fieldValue = dv.el("span", managedField.value || "", attrs); fieldContainer.appendChild(fieldValue); const editBtn = fieldContainer.createEl("button"); const spacer = fieldContainer.createDiv({ cls: "spacer-1" }); if ((_a = attrs.options) == null ? void 0 : _a.alwaysOn) spacer.hide(); (0, import_obsidian28.setIcon)(editBtn, getIcon(managedField.type)); if (!((_b = attrs == null ? void 0 : attrs.options) == null ? void 0 : _b.alwaysOn)) { editBtn.hide(); spacer.show(); fieldContainer.onmouseover = () => { editBtn.show(); spacer.hide(); }; fieldContainer.onmouseout = () => { var _a2; editBtn.hide(); if (!((_a2 = attrs.options) == null ? void 0 : _a2.alwaysOn)) spacer.show(); }; } editBtn.onclick = async () => { managedField.openModal(); fieldValue.hide(); editBtn.hide(); spacer.hide(); }; } function actions22(plugin, field2, file, location, indexedPath) { return actions20(plugin, field2, file, location, indexedPath); } function validateValue22(managedField) { try { parse(managedField.value); return true; } catch (e) { return false; } } function dumpValue(value) { return `${stringify3(value, { lineWidth: 50 }) || ""}`; } // src/options/FieldCommandSuggestModal.ts var import_obsidian29 = require("obsidian"); var FieldCommandSuggestModal = class extends import_obsidian29.FuzzySuggestModal { constructor(app2) { super(app2); this.options = []; this.containerEl.addClass("metadata-menu"); } getItems() { return this.options; } getItemText(item) { return item.actionLabel; } onChooseItem(item, evt) { item.action(); } renderSuggestion(item, el) { if (item.item.id === "__optionSeparator") { el.addClass("suggest-separator"); } else { el.addClass("value-container"); const iconContainer = el.createDiv({ cls: "icon-container" }); item.item.icon ? (0, import_obsidian29.setIcon)(iconContainer, item.item.icon) : (0, import_obsidian29.setIcon)(iconContainer, "pencil"); const actionLabel = el.createDiv(); actionLabel.innerHTML = item.item.actionLabel; } } }; // src/options/OptionsList.ts var import_obsidian59 = require("obsidian"); // src/fields/base/BaseField.ts function isFieldOptions(param) { const _param = param; const isTheRightOption = (options2) => { return Object.keys(options2).every((option) => Object.keys(param[1]).includes(option)); }; return fieldTypes.includes(_param[0]) && isTheRightOption(_param[1]); } // src/fileClass/fileClassAttribute.ts var FileClassAttribute = class { constructor(plugin, name, id, type = "Input", options2 = [], fileClassName, command, display, style, path) { this.plugin = plugin; this.name = name; this.id = id; this.type = type; this.options = options2; this.fileClassName = fileClassName; this.command = command; this.display = display; this.style = style; this.path = path; } getLevel() { if (!this.path) return 0; return this.path.split("____").length; } getField() { var _a; let options2 = {}; if (Array.isArray(this.options)) { (_a = this.options) == null ? void 0 : _a.forEach((option, index) => { options2[index] = option; }); } else { options2 = this.options; } return getField(this.id, this.fileClassName, this.plugin); } getIField() { var _a; let options2 = {}; if (Array.isArray(this.options)) { (_a = this.options) == null ? void 0 : _a.forEach((option, index) => { options2[index] = option; }); } else { options2 = this.options; } if (isFieldOptions([this.type, options2])) { const iField = buildField(this.plugin, this.name, this.id, this.path || "", this.fileClassName, this.command, this.display, this.style, ...[this.type, options2]); return new iField(); } else { console.error(`${this.fileClassName}'s attribute [${this.name}] is not properly set. Check the fileclass settings or delete and recreate it`); } } getOptionsString(plugin) { const field2 = getField(this.id, this.fileClassName, this.plugin); if (field2) return getOptionStr(field2.type)(field2); } }; // src/fileClass/fileClass.ts var import_obsidian30 = require("obsidian"); // src/utils/textUtils.ts var capitalize = (s) => { return s && s[0].toUpperCase() + s.slice(1); }; // src/fileClass/fileClass.ts var options = { "limit": { name: "limit", toValue: (value) => value }, "mapWithTag": { name: "mapWithTag", toValue: (value) => value }, "icon": { name: "icon", toValue: (value) => `${value || "file-spreadsheet"}` }, "tagNames": { name: "tagNames", toValue: (values) => values.length ? values : null }, "filesPaths": { name: "filesPaths", toValue: (values) => values.length ? values : null }, "bookmarksGroups": { name: "bookmarksGroups", toValue: (values) => values.length ? values : null }, "excludes": { name: "excludes", toValue: (values) => values.length ? values.map((attr) => attr.name) : null }, "parent": { name: "extends", toValue: (value) => (value == null ? void 0 : value.name) || null }, "savedViews": { name: "savedViews", toValue: (value) => value }, "favoriteView": { name: "favoriteView", toValue: (value) => value || null }, "fieldsOrder": { name: "fieldsOrder", toValue: (value) => value || [] } }; var FileClassOptions = class { constructor(limit, icon, parent, excludes, tagNames, mapWithTag = false, filesPaths, bookmarksGroups, savedViews, favoriteView, fieldsOrder) { this.limit = limit; this.icon = icon; this.parent = parent; this.excludes = excludes; this.tagNames = tagNames; this.mapWithTag = mapWithTag; this.filesPaths = filesPaths; this.bookmarksGroups = bookmarksGroups; this.savedViews = savedViews; this.favoriteView = favoriteView; this.fieldsOrder = fieldsOrder; } }; var AddFileClassToFileModal = class extends import_obsidian30.SuggestModal { constructor(plugin, file) { super(plugin.app); this.plugin = plugin; this.file = file; } getSuggestions(query) { const fileClasses = [...this.plugin.fieldIndex.fileClassesName.keys()].filter( (fileClassName) => { var _a; return !((_a = this.plugin.fieldIndex.filesFileClasses.get(this.file.path)) == null ? void 0 : _a.map((fileClass) => fileClass.name).includes(fileClassName)); } ).filter((fileClassName) => fileClassName.toLocaleLowerCase().contains(query.toLowerCase())).sort(); return fileClasses; } renderSuggestion(value, el) { el.setText(value); el.setAttr("id", `fileclass-${value}-add-choice`); } onChooseSuggestion(item, evt) { this.insertFileClassToFile(item); } async insertFileClassToFile(value) { const fileClassAlias = this.plugin.settings.fileClassAlias; const currentFileClasses = this.plugin.fieldIndex.filesFileClasses.get(this.file.path); const newValue = currentFileClasses ? [...currentFileClasses.map((fc) => fc.name), value].join(", ") : value; await postValues(this.plugin, [{ indexedPath: `fileclass-field-${fileClassAlias}`, payload: { value: newValue } }], this.file, -1); if (this.plugin.settings.autoInsertFieldsAtFileClassInsertion) { insertMissingFields(this.plugin, this.file, -1); } } }; var FileClass = class { constructor(plugin, name) { this.plugin = plugin; this.name = name; this.attributes = []; } getFileClassOptions() { var _a, _b; const { extends: _parent, limit: _limit, excludes: _excludes, mapWithTag: _mapWithTag, tagNames: _tagNames, filesPaths: _filesPaths, bookmarksGroups: _bookmarksGroups, icon: _icon, savedViews: _savedViews, favoriteView: _favoriteView, fieldsOrder: _fieldsOrder } = ((_a = this.plugin.app.metadataCache.getFileCache(this.getClassFile())) == null ? void 0 : _a.frontmatter) || {}; const index = this.plugin.fieldIndex; const parent = index.fileClassesName.get(_parent); const excludedNames = getExcludedFieldsFromFrontmatter(_excludes); const excludes = []; (_b = index.fileClassesAncestors.get(this.getClassFile().basename)) == null ? void 0 : _b.forEach((ancestorName) => { var _a2; (_a2 = index.fileClassesName.get(ancestorName)) == null ? void 0 : _a2.attributes.forEach((attr) => { if (excludedNames.includes(attr.name) && !excludes.map((attr2) => attr2.name).includes(attr.name)) excludes.push(attr); }); }); const limit = typeof _limit === "number" ? _limit : this.plugin.settings.tableViewMaxRecords; const mapWithTag = stringToBoolean(_mapWithTag); const tagNames = getTagNamesFromFrontMatter(_tagNames); const filesPaths = getFilesPathsFromFrontMatter(_filesPaths); const bookmarksGroups = getBookmarksGroupsFromFrontMatter(_bookmarksGroups); const icon = typeof _icon === "string" ? _icon : this.plugin.settings.fileClassIcon; const savedViews = _savedViews || []; const favoriteView = typeof _favoriteView === "string" && _favoriteView !== "" ? _favoriteView : null; const fieldsOrder = _fieldsOrder || []; return new FileClassOptions(limit, icon, parent, excludes, tagNames, mapWithTag, filesPaths, bookmarksGroups, savedViews, favoriteView, fieldsOrder); } isMappedWithTag() { var _a, _b; try { const fileClassFile = this.getClassFile(); const mapWithTag = (_b = (_a = this.plugin.app.metadataCache.getFileCache(fileClassFile)) == null ? void 0 : _a.frontmatter) == null ? void 0 : _b.mapWithTag; return !!mapWithTag; } catch (error) { return false; } } getClassFile() { const filesClassPath = this.plugin.settings.classFilesPath; const file = this.plugin.app.vault.getAbstractFileByPath(`${filesClassPath}${this.name}.md`); if (file instanceof import_obsidian30.TFile && file.extension == "md") { return file; } else { const error = new Error( `no file named <${this.name}.md> in <${filesClassPath}> folder to match <${this.plugin.settings.fileClassAlias}: ${this.name}> in one of these notes` ); throw error; } } getIcon() { const parents = [this.name, ...this.plugin.fieldIndex.fileClassesAncestors.get(this.name) || []]; let icon; parents.some((fileClassName, i) => { var _a, _b; const fileClass = this.plugin.fieldIndex.fileClassesName.get(fileClassName); if (fileClass) { const file = fileClass.getClassFile(); const _icon = (_b = (_a = this.plugin.app.metadataCache.getFileCache(file)) == null ? void 0 : _a.frontmatter) == null ? void 0 : _b.icon; if (_icon) { icon = _icon; return true; } ; } }); return icon || this.plugin.settings.fileClassIcon; } async missingFieldsForFileClass(file) { var _a; const note = await Note.buildNote(this.plugin, file); const currentFieldsIds = note.existingFields.map((_f) => _f.field.id); const missingFields = this && file ? !((_a = this.plugin.fieldIndex.fileClassesFields.get(this.name)) == null ? void 0 : _a.map((f) => f.id).every((id) => currentFieldsIds.includes(id))) : false; return missingFields; } moveField(thisId, direction) { var _a; const thisPath = (_a = getFileClassAttributes(this.plugin, this).find((attr) => attr.id === thisId)) == null ? void 0 : _a.path; const sortedPaths = []; for (const attr of buildSortedAttributes(this.plugin, this)) { sortedPaths.push({ id: attr.id, path: attr.getField().path }); } const compareShortId = (a) => a.id === thisId && a.path === thisPath; const thisIndex = sortedPaths.findIndex(compareShortId); let newIndex = thisIndex; const testPath = (j) => { if (sortedPaths[j].path === thisPath) { newIndex = j; return true; } return false; }; if (direction === "upwards" && thisIndex > 0) { for (let j = thisIndex - 1; j >= 0; j--) if (testPath(j)) break; } else if (direction === "downwards" && thisIndex < sortedPaths.length) { for (let j = thisIndex + 1; j < sortedPaths.length; j++) if (testPath(j)) break; } [sortedPaths[thisIndex], sortedPaths[newIndex]] = [sortedPaths[newIndex], sortedPaths[thisIndex]]; this.options.fieldsOrder = sortedPaths.map((p) => p.id); this.updateOptions(this.options); } getViewChildren(name) { var _a, _b; if (!name) return []; const childrenNames = ((_b = (_a = this.getFileClassOptions().savedViews) == null ? void 0 : _a.find((_view) => _view.name === name)) == null ? void 0 : _b.children) || []; return this.getChildren().filter((c) => childrenNames.includes(c.name)); } getAttributes() { var _a, _b; try { const file = this.getClassFile(); const ancestors = this.plugin.fieldIndex.fileClassesAncestors.get(this.name); const _excludedFields = (_b = (_a = this.plugin.app.metadataCache.getFileCache(file)) == null ? void 0 : _a.frontmatter) == null ? void 0 : _b.excludes; let excludedFields = getExcludedFieldsFromFrontmatter(_excludedFields); const ancestorsAttributes = /* @__PURE__ */ new Map(); ancestorsAttributes.set(this.name, getFileClassAttributes(this.plugin, this, excludedFields)); ancestors == null ? void 0 : ancestors.forEach((ancestorName) => { var _a2, _b2; const ancestorFile = this.plugin.app.vault.getAbstractFileByPath(`${this.plugin.settings.classFilesPath}${ancestorName}.md`); const ancestor = new FileClass(this.plugin, ancestorName); ancestorsAttributes.set(ancestorName, getFileClassAttributes(this.plugin, ancestor, excludedFields)); if (ancestorFile instanceof import_obsidian30.TFile && ancestorFile.extension === "md") { const _excludedFields2 = (_b2 = (_a2 = this.plugin.app.metadataCache.getFileCache(ancestorFile)) == null ? void 0 : _a2.frontmatter) == null ? void 0 : _b2.excludes; excludedFields.push(...getExcludedFieldsFromFrontmatter(_excludedFields2)); } }); for (const [fileClassName, fileClassAttributes] of ancestorsAttributes) { this.attributes.push(...fileClassAttributes.filter((attr) => !this.attributes.map((_attr) => _attr.name).includes(attr.name))); } } catch (error) { throw error; } } getVersion() { var _a, _b; return (_b = (_a = this.plugin.app.metadataCache.getFileCache(this.getClassFile())) == null ? void 0 : _a.frontmatter) == null ? void 0 : _b.version; } getMajorVersion() { const version = this.getVersion(); if (version) { const [x, y] = `${version}`.split("."); if (!y) return void 0; return parseInt(x); } else { return void 0; } } async incrementVersion() { var _a, _b; const file = this.getClassFile(); const currentVersion = (_b = (_a = this.plugin.app.metadataCache.getFileCache(file)) == null ? void 0 : _a.frontmatter) == null ? void 0 : _b.version; await this.plugin.app.fileManager.processFrontMatter(file, (fm) => { if (currentVersion) { const [x, y] = currentVersion.split("."); fm.version = `${x}.${parseInt(y) + 1}`; } else { fm.version = "2.0"; } }); } async updateOptions(newOptions) { const file = this.getClassFile(); await this.plugin.app.fileManager.processFrontMatter(file, (fm) => { Object.keys(options).forEach(async (key) => { const { name, toValue } = options[key]; fm[name] = toValue(newOptions[key]); }); }); await this.incrementVersion(); } getChildren() { const childrenNames = []; [...this.plugin.fieldIndex.fileClassesAncestors].forEach(([_fName, ancestors]) => { if (ancestors.includes(this.name)) { const path = [...ancestors.slice(0, ancestors.indexOf(this.name)).reverse(), _fName]; const fileClass = this.plugin.fieldIndex.fileClassesName.get(_fName); if (fileClass) { childrenNames.push({ name: _fName, path, fileClass }); } } }); return childrenNames; } async updateAttribute(newType, newName, newOptions, attr, newCommand, newDisplay, newStyle, newPath) { const fileClass = attr ? this.plugin.fieldIndex.fileClassesName.get(attr.fileClassName) : this; const file = fileClass.getClassFile(); await this.plugin.app.fileManager.processFrontMatter(file, (fm) => { fm.fields = fm.fields || []; if (attr) { const field2 = fm.fields.find((f) => f.id === attr.id); field2.type = newType; if (newOptions) field2.options = newOptions; if (newCommand) field2.command = newCommand; if (newDisplay) field2.display = newDisplay; if (newStyle) field2.style = newStyle; if (newName) field2.name = newName; if (newPath !== void 0) field2.path = newPath; } else { fm.fields.push({ name: newName, type: newType, options: newOptions, command: newCommand, display: newDisplay, style: newStyle, path: newPath, id: getNewFieldId(this.plugin) }); } }); await this.incrementVersion(); } async updateIAttribute(attr, newType, newName, newOptions, newCommand, newDisplay, newStyle, newPath) { const fileClass = attr && attr.fileClassName ? this.plugin.fieldIndex.fileClassesName.get(attr.fileClassName) : this; const file = fileClass.getClassFile(); await this.plugin.app.fileManager.processFrontMatter(file, (fm) => { fm.fields = fm.fields || []; const field2 = fm.fields.find((f) => f.id === attr.id); if (field2) { field2.type = newType; if (newOptions) field2.options = newOptions; if (newCommand) field2.command = newCommand; if (newDisplay) field2.display = newDisplay; if (newStyle) field2.style = newStyle; if (newName) field2.name = newName; if (newPath !== void 0) field2.path = newPath; } else { fm.fields.push({ name: newName, type: newType, options: newOptions, command: newCommand, display: newDisplay, style: newStyle, path: newPath, id: getNewFieldId(this.plugin) }); } }); await this.incrementVersion(); } async removeAttribute(attr) { const file = this.getClassFile(); await this.plugin.app.fileManager.processFrontMatter(file, (fm) => { fm.fields = fm.fields.filter((f) => f.id !== attr.id); }); } async removeIAttribute(attr) { const file = this.getClassFile(); await this.plugin.app.fileManager.processFrontMatter(file, (fm) => { fm.fields = fm.fields.filter((f) => f.id !== attr.id); }); } }; function buildSortedAttributes(plugin, fileClass) { const attributes = getFileClassAttributes(plugin, fileClass); const options2 = fileClass.getFileClassOptions(); const presetOrder = options2.fieldsOrder || []; attributes.sort( (a, b) => presetOrder.indexOf(a.id) > presetOrder.indexOf(b.id) ? 1 : -1 ); const sortedAttributes = attributes.filter((attr) => !attr.path); let hasError = false; while (sortedAttributes.length < attributes.length) { const _initial = [...sortedAttributes]; sortedAttributes.forEach((sAttr, parentIndex) => { var _a; for (const attr of attributes) { if (((_a = attr.path) == null ? void 0 : _a.split("____").last()) === sAttr.id && !sortedAttributes.includes(attr)) { const parentLevel = sAttr.getLevel(); const parentSibling = sortedAttributes.slice(parentIndex + 1).find((oAttr) => oAttr.getLevel() <= parentLevel); const parentSiblingIndex = parentSibling ? sortedAttributes.indexOf(parentSibling) : sortedAttributes.length; sortedAttributes.splice(parentSiblingIndex, 0, attr); break; } } }); if (_initial.length === sortedAttributes.length) { console.error("Impossible to restore field hierarchy, check you fileclass configuration"); new import_obsidian30.Notice("Impossible to restore field hierarchy, check you fileclass configuration"); hasError = true; return getFileClassAttributes(plugin, fileClass); } } options2.fieldsOrder = sortedAttributes.map((sAttr) => sAttr.id); if (!compareArrays(presetOrder, options2.fieldsOrder)) fileClass.updateOptions(options2); return sortedAttributes; } function createFileClass(plugin, name) { const fileClass = new FileClass(plugin, name); fileClass.options = fileClass.getFileClassOptions(); fileClass.getAttributes(); return fileClass; } function getBookmarksGroupsFromFrontMatter(_bookmarksGroups) { if (Array.isArray(_bookmarksGroups)) { return _bookmarksGroups; } else if (_bookmarksGroups) { return _bookmarksGroups.split(","); } else { return []; } } function getExcludedFieldsFromFrontmatter(excludedFields) { if (Array.isArray(excludedFields)) { return excludedFields; } else if (excludedFields) { return excludedFields.split(","); } else { return []; } } function getFileClassAttributes(plugin, fileClass, excludes) { var _a, _b; const file = fileClass.getClassFile(); const rawAttributes = ((_b = (_a = plugin.app.metadataCache.getFileCache(file)) == null ? void 0 : _a.frontmatter) == null ? void 0 : _b.fields) || []; const attributes = []; rawAttributes.forEach((attr) => { const { name, id, type, options: options2, command, display, style, path } = attr; const fieldType = capitalize(type); attributes.push(new FileClassAttribute(plugin, name, id, fieldType, options2, fileClass.name, command, display, style, path)); }); if (excludes) { return attributes.filter((attr) => !excludes.includes(attr.name)); } else { return attributes; } } function getFileClassNameFromPath(settings, path) { var _a, _b; const fileClassNameRegex = new RegExp(`${settings.classFilesPath}(?.*).md`); return (_b = (_a = path.match(fileClassNameRegex)) == null ? void 0 : _a.groups) == null ? void 0 : _b.fileClassName; } function getFilesPathsFromFrontMatter(_filesPaths) { if (Array.isArray(_filesPaths)) { return _filesPaths; } else if (_filesPaths) { return _filesPaths.split(","); } else { return []; } } function getSortedRootFields(plugin, fileClass) { var _a; const fieldsOrder = fileClass.fieldsOrder || buildSortedAttributes(plugin, fileClass).map((attr) => attr.id); const iFinder = (f) => { return (id) => f.id === id; }; const fields = ((_a = plugin.fieldIndex.fileClassesFields.get(fileClass.name)) == null ? void 0 : _a.filter((_f) => _f.isRoot())) || []; const sortedFields = fields.sort((f1, f2) => { return fieldsOrder.findIndex(iFinder(f1)) < fieldsOrder.findIndex(iFinder(f2)) ? -1 : 1; }); return sortedFields; } function sortFileFields(index, file) { const fileClasses = index.filesFileClasses.get(file.path) || []; const sortedAttributes = []; for (const fileClass of fileClasses) { const fileClassFields = index.fileClassesFields.get(fileClass.name) || []; const order2 = fileClass.options.fieldsOrder; const sortedFields = order2 ? fileClassFields.sort((f1, f2) => order2.indexOf(f1.id) < order2.indexOf(f2.id) ? -1 : 1) : fileClassFields; sortedAttributes.push(...sortedFields); } return sortedAttributes; } function getTagNamesFromFrontMatter(_tagNames) { if (Array.isArray(_tagNames)) { return _tagNames; } else if (_tagNames) { return _tagNames.split(","); } else { return []; } } function indexFileClass(index, file) { var _a, _b, _c, _d, _e, _f, _g; const fileClassName = getFileClassNameFromPath(index.plugin.settings, file.path); if (fileClassName) { try { const fileClass = createFileClass(index.plugin, fileClassName); index.fileClassesFields.set( fileClassName, fileClass.attributes.map((attr) => attr.getIField()).filter( (field2) => field2 !== void 0 /* in case getIField doesn't resolve the field won't be added and the error will be silent*/ ) ); index.fileClassesPath.set(file.path, fileClass); index.fileClassesName.set(fileClass.name, fileClass); const cache = index.plugin.app.metadataCache.getFileCache(file); if ((fileClass.getMajorVersion() === void 0 || fileClass.getMajorVersion() < 2) && index.plugin.manifest.version < "0.6.0") { index.v1FileClassesPath.set(file.path, fileClass); index.remainingLegacyFileClasses = true; } if ((_a = cache == null ? void 0 : cache.frontmatter) == null ? void 0 : _a.mapWithTag) { if (!fileClassName.includes(" ")) { index.tagsMatchingFileClasses.set(fileClassName, fileClass); } } if ((_b = cache == null ? void 0 : cache.frontmatter) == null ? void 0 : _b.tagNames) { const _tagNames = (_c = cache == null ? void 0 : cache.frontmatter) == null ? void 0 : _c.tagNames; const tagNames = Array.isArray(_tagNames) ? [..._tagNames] : _tagNames.split(",").map((t) => t.trim()); tagNames.forEach((tag) => { if (!tag.includes(" ")) { index.tagsMatchingFileClasses.set(tag, fileClass); } }); } if ((_d = cache == null ? void 0 : cache.frontmatter) == null ? void 0 : _d.filesPaths) { const _filesPaths = (_e = cache == null ? void 0 : cache.frontmatter) == null ? void 0 : _e.filesPaths; const filesPaths = Array.isArray(_filesPaths) ? [..._filesPaths] : _filesPaths.split(",").map((f) => f.trim()); filesPaths.forEach((path) => index.filesPathsMatchingFileClasses.set(path, fileClass)); } if ((_f = cache == null ? void 0 : cache.frontmatter) == null ? void 0 : _f.bookmarksGroups) { const _bookmarksGroups = (_g = cache == null ? void 0 : cache.frontmatter) == null ? void 0 : _g.bookmarksGroups; const bookmarksGroups = Array.isArray(_bookmarksGroups) ? [..._bookmarksGroups] : _bookmarksGroups.split(",").map((g) => g.trim()); bookmarksGroups.forEach((group) => index.bookmarksGroupsMatchingFileClasses.set(group, fileClass)); } } catch (error) { console.error(error); } } } // src/modals/AddNewFileClassModal.ts var import_obsidian31 = require("obsidian"); var AddNewFileClassModal = class extends import_obsidian31.Modal { constructor(plugin) { super(plugin.app); this.plugin = plugin; this.containerEl.addClass("metadata-menu"); this.containerEl.setAttr("id", "add-new-fileclass-modal"); } onOpen() { this.titleEl.setText("Add a new fileClass"); this.containerEl.onkeydown = async (e) => { if (e.key == "Enter" && e.altKey) { e.preventDefault(); await this.save(); } if (e.key === "Escape" && e.altKey) { this.close(); } }; this.buildAddFileClassForm(); } buildAddFileClassForm() { const fileClassesPath = this.plugin.settings.classFilesPath; const fileClassAlias = this.plugin.settings.fileClassAlias; const nameContainer = this.contentEl.createDiv({ cls: "field-container" }); nameContainer.createDiv({ text: `${fileClassAlias} name`, cls: "label" }); const nameInput = new import_obsidian31.TextComponent(nameContainer); nameInput.inputEl.addClass("with-label"); nameInput.inputEl.addClass("full-width"); nameInput.inputEl.setAttr("id", "fileclass-name-input"); const nameErrorContainer = this.contentEl.createDiv({ cls: "field-error", text: `This ${fileClassAlias} file already exists` }); cleanActions(this.contentEl, ".footer-actions"); const actionsContainer = this.contentEl.createDiv({ cls: "footer-actions" }); actionsContainer.createDiv({ cls: "spacer" }); const infoContainer = actionsContainer.createDiv({ cls: "info" }); infoContainer.setText("Alt+Enter to save"); const saveBtn = new import_obsidian31.ButtonComponent(actionsContainer).setDisabled(true).setIcon("file-plus-2"); saveBtn.buttonEl.setAttr("id", "new-fileclass-confirm-btn"); nameErrorContainer.hide(); nameInput.onChange(async (value) => { this.name = nameInput.getValue(); nameErrorContainer.hide(); saveBtn.setDisabled(false); saveBtn.setCta(); if (await this.plugin.app.vault.adapter.exists(`${fileClassesPath}${value}.md`)) { nameErrorContainer.show(); saveBtn.setDisabled(true); saveBtn.removeCta(); } else { saveBtn.setDisabled(false); saveBtn.setCta(); } }); saveBtn.onClick(async () => await this.save()); } async save() { const fileClassName = this.name; const classFilesPath = this.plugin.settings.classFilesPath; let fCFile; const openAfterCreate = this.plugin.fieldIndex.openFileClassManagerAfterIndex; if (classFilesPath) { try { openAfterCreate.push(fileClassName); fCFile = await this.plugin.app.vault.create(`${classFilesPath}${fileClassName}.md`, "---\n---"); } catch (error) { openAfterCreate.remove(fileClassName); new import_obsidian31.Notice("Something went wrong. Impossible to create this fileClass", 3e3); return; } } this.close(); } }; // src/utils/dataviewUtils.ts function genuineKeys(obj, depth = 0) { const reservedKeys = ["file", "aliases", "tags"]; const _genuineKeys = []; for (const key of Object.keys(obj)) { if (depth === 0 && reservedKeys.includes(key)) continue; if (typeof obj[key] === "object" && obj[key] !== null) { if (!_genuineKeys.map((k) => k.toLowerCase().replace(/\s/g, "-")).includes(key.toLowerCase().replace(/\s/g, "-"))) { _genuineKeys.push(key); } _genuineKeys.push(...genuineKeys(obj[key], depth + 1).filter((k) => !_genuineKeys.includes(k))); } else if (!_genuineKeys.map((k) => k.toLowerCase().replace(/\s/g, "-")).includes(key.toLowerCase().replace(/\s/g, "-"))) { _genuineKeys.push(key); } else { if (key !== key.toLowerCase().replace(/\s/g, "-")) { _genuineKeys[_genuineKeys.indexOf(key.toLowerCase().replace(/\s/g, "-"))] = key; } } } return _genuineKeys; } function legacyGenuineKeys(dvFile) { const genuineKeys2 = []; if (dvFile) Object.keys(dvFile).forEach((key) => { if (!genuineKeys2.map((k) => k.toLowerCase().replace(/\s/g, "-")).includes(key.toLowerCase().replace(/\s/g, "-"))) { genuineKeys2.push(key); } else { if (key !== key.toLowerCase().replace(/\s/g, "-")) { genuineKeys2[genuineKeys2.indexOf(key.toLowerCase().replace(/\s/g, "-"))] = key; } } }); return genuineKeys2; } // src/modals/chooseSectionModal.ts var import_obsidian32 = require("obsidian"); var chooseSectionModal = class extends import_obsidian32.SuggestModal { constructor(plugin, file, onSelect) { super(plugin.app); this.plugin = plugin; this.file = file; this.onSelect = onSelect; this.addAsListItem = false; this.addAsComment = false; this.addAtEndOfFrontMatter = false; this.onSelect = onSelect; this.containerEl.addClass("metadata-menu"); this.resultContainerEl.addClass("sections"); } onOpen() { super.onOpen(); const inputContainer = this.containerEl.createDiv({ cls: "suggester-input" }); inputContainer.appendChild(this.inputEl); this.containerEl.find(".prompt").prepend(inputContainer); const addAsListItemBtn = new import_obsidian32.ButtonComponent(inputContainer); addAsListItemBtn.setIcon("list"); addAsListItemBtn.onClick(() => { if (this.addAsListItem) { addAsListItemBtn.removeCta(); this.addAsListItem = false; } else { addAsListItemBtn.setCta(); this.addAsListItem = true; } }); addAsListItemBtn.setDisabled(this.addAtEndOfFrontMatter); addAsListItemBtn.setTooltip("Add this field as a list item"); const addAsCommentItemBtn = new import_obsidian32.ButtonComponent(inputContainer); addAsCommentItemBtn.setIcon("message-square"); addAsCommentItemBtn.onClick(() => { if (this.addAsComment) { addAsCommentItemBtn.removeCta(); this.addAsComment = false; } else { addAsCommentItemBtn.setCta(); this.addAsComment = true; } }); addAsCommentItemBtn.setDisabled(this.addAtEndOfFrontMatter); addAsCommentItemBtn.setTooltip("Add this field as a comment item"); const addAtEndOfFrontMatterBtn = new import_obsidian32.ButtonComponent(inputContainer); addAtEndOfFrontMatterBtn.setIcon("align-vertical-space-around"); addAtEndOfFrontMatterBtn.onClick(() => { this.onSelect(-1, false, false); this.close(); }); addAtEndOfFrontMatterBtn.setTooltip("Add this field at the end of the frontmatter"); } async getSuggestions(query) { const content = await this.plugin.app.vault.read(this.file); const suggestions = [{ lineNumber: -1, lineText: "----------Add on top of the file--------" }]; content.split("\n").forEach((lineContent, i) => { if (lineContent.toLowerCase().includes(query.toLowerCase())) { suggestions.push({ lineNumber: i, lineText: lineContent.substring(0, 57) + (lineContent.length < 57 ? "" : "...") }); } }); return suggestions; } renderSuggestion(value, el) { el.addClass("item"); const container = el.createDiv({ cls: "line" }); container.createDiv({ text: `${value.lineNumber + 1}`, cls: "lineNumber" }); container.createDiv({ text: value.lineText, cls: "lineText" }); } onChooseSuggestion(item, evt) { this.onSelect( item.lineNumber == -1 ? 0 : item.lineNumber, this.addAsListItem, this.addAsComment ); } }; // src/options/FileClassOptionsList.ts var import_obsidian58 = require("obsidian"); // src/components/FileClassViewManager.ts var import_obsidian57 = require("obsidian"); // src/fileClass/views/fileClassView.ts var import_obsidian55 = require("obsidian"); // src/fileClass/views/fileClassFieldsView.ts var import_obsidian44 = require("obsidian"); // src/commands/removeFileClassAttribute.ts async function removeFileClassAttributeWithId(plugin, fileClass, id) { const file = fileClass.getClassFile(); if (file) { await plugin.app.fileManager.processFrontMatter(file, (fm) => { fm.fields = fm.fields.filter((f) => f.id !== id); }); } } // src/fields/base/BaseSetting.ts var import_obsidian34 = require("obsidian"); // src/settings/FieldSetting.ts var import_obsidian33 = require("obsidian"); var FieldSetting = class extends import_obsidian33.Setting { constructor(containerEl, field2, plugin) { super(containerEl); this.containerEl = containerEl; this.field = field2; this.plugin = plugin; this.setTextContentWithname(); this.addEditButton(); this.addDeleteButton(); this.settingEl.addClass("no-border"); } setTextContentWithname() { const field2 = getField(this.field.id, this.field.fileClassName, this.plugin); if (!field2) return; this.infoEl.textContent = ""; this.infoEl.addClass("setting-item"); this.fieldNameContainer = this.infoEl.createDiv({ cls: "name" }); const level = !this.field.path ? 0 : this.field.path.split("____").length; for (let i = 0; i < level; i++) { const indentation = this.fieldNameContainer.createDiv({ cls: "indentation" }); if (i === level - 1) { (0, import_obsidian33.setIcon)(indentation, "corner-down-right"); } } this.fieldNameContainer.createDiv({ text: `${this.field.name}` }); this.typeContainer = this.infoEl.createEl("div"); this.typeContainer.setAttr("class", `chip ${getTagName(this.field.type)}`); this.typeContainer.setText(this.field.type); this.fieldOptionsContainer = this.infoEl.createEl("div"); this.fieldOptionsContainer.setText(`${getOptionStr(field2.type)(field2)}`); } addEditButton() { this.addButton((b) => { b.setIcon("pencil").setTooltip("Edit").onClick(() => { openSettings(this.field.id, void 0, this.plugin, this, this.containerEl); }); }); } addDeleteButton() { this.addButton((b) => { b.setIcon("trash").setTooltip("Delete").onClick(() => { var _a; const currentExistingProperty = this.plugin.presetFields.filter((p) => p.id == this.field.id)[0]; if (currentExistingProperty) { this.plugin.presetFields.remove(currentExistingProperty); } ; (_a = this.settingEl.parentElement) == null ? void 0 : _a.removeChild(this.settingEl); this.plugin.saveSettings(); }); }); } static async getValuesListFromNote(plugin, notePath) { let values = []; const file = plugin.app.vault.getAbstractFileByPath(notePath); if (file instanceof import_obsidian33.TFile && file.extension == "md") { const result = await plugin.app.vault.read(file); result.split("\n").forEach((line) => { if (/^(.*)$/.test(line)) { values.push(line.trim()); } ; }); return values; } else { return []; } ; } }; // src/settings/MetadataMenuSettings.ts var DEFAULT_SETTINGS = { presetFields: [], fileClassQueries: [], displayFieldsInContextMenu: true, globallyIgnoredFields: [], classFilesPath: null, isAutosuggestEnabled: true, fileClassAlias: "fileClass", settingsVersion: void 0, globalFileClass: void 0, firstDayOfWeek: 1, enableLinks: true, enableTabHeader: true, enableEditor: true, enableBacklinks: true, enableStarred: true, enableFileExplorer: true, enableSearch: true, enableProperties: true, tableViewMaxRecords: 20, frontmatterListDisplay: "asArray" /* asArray */, fileClassExcludedFolders: [], showIndexingStatusInStatusBar: true, fileIndexingExcludedFolders: [], fileIndexingExcludedExtensions: [".excalidraw.md"], fileIndexingExcludedRegex: [], frontmatterOnly: false, showFileClassSelectInModal: true, chooseFileClassAtFileCreation: false, autoInsertFieldsAtFileClassInsertion: false, fileClassIcon: "package", isAutoCalculationEnabled: true }; var incrementVersion = (plugin) => { const currentVersion = plugin.settings.settingsVersion; if (currentVersion && typeof currentVersion === "string") { const [x, y] = currentVersion.split("."); plugin.settings.settingsVersion = `${x}.${parseInt(y) + 1}`; } else { plugin.settings.settingsVersion = "5.0"; } }; // src/fields/base/BaseSetting.ts var TypeSelector = class extends import_obsidian34.SuggestModal { constructor(plugin, fieldSetting, labelContainer) { super(plugin.app); this.plugin = plugin; this.fieldSetting = fieldSetting; this.labelContainer = labelContainer; this.containerEl.addClass("metadata-menu"); } getSuggestions(query) { const _fieldTypes = []; for (const fieldType of fieldTypes) { if (!rootOnlyTypes.includes(fieldType)) { _fieldTypes.push(fieldType); } else { if (this.fieldSetting.field.isRoot()) _fieldTypes.push(fieldType); } } return _fieldTypes.filter((k) => k.toLowerCase().includes(query.toLowerCase())); } renderSuggestion(value, el) { el.addClass("value-container"); el.addClass(`field-type-${value}`); const iconContainer = el.createDiv({ cls: "icon-container" }); (0, import_obsidian34.setIcon)(iconContainer, getIcon(value)); const chipContainer = el.createDiv({ cls: "field-type-container" }); chipContainer.createDiv({ text: value, cls: `chip ${getTagName(value)}` }); chipContainer.createDiv({ cls: "spacer" }); el.createDiv({ cls: "field-type-tooltip", text: getTooltip(value) }); } onChooseSuggestion(item, evt) { this.fieldSetting.setType(item, this.labelContainer); } }; var ParentSelector = class extends import_obsidian34.SuggestModal { constructor(plugin, fieldSetting, compatibleParents) { super(plugin.app); this.plugin = plugin; this.fieldSetting = fieldSetting; this.compatibleParents = compatibleParents; } getSuggestions(query) { const parents = this.compatibleParents.filter((p) => p.name.toLowerCase().includes(query.toLowerCase())); return parents; } renderSuggestion(parent, el) { const path = getParentPath(parent); const display = getHierarchyDisplay( this.plugin, path, this.fieldSetting.getFileClassName() ); el.setText(display); } onChooseSuggestion(parent, evt) { this.fieldSetting.setParent(parent); } }; function getHierarchyDisplay(plugin, path, fileClassName) { const display = path.split("____").map((id) => { var _a; return ((_a = getField(id, fileClassName, plugin)) == null ? void 0 : _a.name) || ""; }).join(" > "); return display; } function getParentPath(item) { const path = item.path ? item.path + "____" + item.id : item.id; return path; } function buildSettingsModal(fieldConstructor, plugin, parentSetting, parentSettingContainer) { return class SettingsModal extends import_obsidian34.Modal { constructor() { super(plugin.app); this.validateOptions = () => true; this.isNew = true; this.saved = false; this.decorationButtons = {}; this.plugin = plugin; this.init(); } init() { this.initialField = new fieldConstructor(); this.field = new (buildEmptyField(plugin, this.initialField.fileClassName, this.initialField.type))(); this.initialField.options = getOptions(this.initialField); copyProperty(this.field, this.initialField); this.isNew = !this.field.id; this.initialField.id = this.initialField.id || getNewFieldId(this.plugin); this.field.id = this.initialField.id; if (this.initialField.fileClassName) this.fileClass = this.plugin.fieldIndex.fileClassesName.get(this.initialField.fileClassName); if (this.fileClass) { this.location = 1 /* FileClassAttributeSettings */; } else { this.location = 0 /* PluginSettings */; } this.path = this.initialField.path; this.addCommand = !!this.field.command; this.command = this.initialField.command || { id: this.field ? `insert__${this.field.id}` : "", icon: "list-plus", label: this.field ? `Insert ${this.field.name} field` : "", hotkey: void 0 }; } onOpen() { this.build(); } build() { this.containerEl.addClass("metadata-menu"); if (this.field.name == "") { this.titleEl.setText(`Add a field and define options`); } else { this.titleEl.setText(`Manage settings options for ${this.field.name}`); } ; this.createnameInputContainer(); this.typeSelectContainer = this.contentEl.createDiv({ cls: "field-container" }); this.parentSelectContainer = this.contentEl.createDiv({ cls: "field-container" }); this.buildParentSelectContainer(); this.contentEl.createEl("hr"); this.createCommandContainer(); this.createFrontmatterListDisplayContainer(); const styleContainer = this.contentEl.createDiv({ cls: "field-container" }); this.contentEl.createEl("hr"); this.optionsContainer = this.contentEl.createDiv(); cleanActions(this.contentEl, ".footer-actions"); const footer = this.contentEl.createDiv({ cls: "footer-actions" }); footer.createDiv({ cls: "spacer" }); this.createSaveButton(footer); if (this.field) this.createRemovalBtn(footer); this.createCancelButton(footer); this.createStyleSelectorContainer(styleContainer); this.buildTypeSelectContainer(); this.createSettingContainer(); } createnameInputContainer() { const container = this.contentEl.createDiv({ cls: "field-container" }); container.createDiv({ cls: "label", text: "Field Name: " }); const input = new import_obsidian34.TextComponent(container); input.inputEl.addClass("with-label"); input.inputEl.addClass("full-width"); input.inputEl.focus(); const name = this.field.name; input.setValue(name); input.setPlaceholder("Name of the field"); input.onChange((value) => { this.field.name = value; this.command.id = `insert__${this.field.fileClassName || "presetField"}__${value}`; this.command.label = `Insert ${value} field`; this.titleEl.setText(`Manage settings options for ${this.field.name}`); removeValidationError(input); }); this.namePromptComponent = input; } setParent(parent) { if (parent === void 0) { this.path = ""; this.field.path = ""; } else { const path = getParentPath(parent); this.path = path; this.field.path = path; } this.buildParentSelectContainer(parent); this.buildTypeSelectContainer(); } getFileClassName() { var _a; return (_a = this.fileClass) == null ? void 0 : _a.name; } buildParentSelectContainer(_parent) { const parent = _parent || this.field.getFirstAncestor(); this.parentSelectContainer.replaceChildren(); const compatibleParents = this.field.getCompatibleParents(); const parentName = parent ? getHierarchyDisplay( this.plugin, getParentPath(parent), this.getFileClassName() ) : "-- No parent field selected --"; this.parentSelectContainer.createDiv({ cls: "label" }).setText(`Parent:`); this.parentSelectContainer.createDiv({ cls: "spacer" }); this.parentSelectContainer.createDiv({ cls: parent ? "parent-label" : "parent-label empty" }).setText(parentName); new import_obsidian34.ButtonComponent(this.parentSelectContainer).setButtonText(`${!this.field.path ? "Select a parent field" : "Change parent field"}`).onClick(() => { new ParentSelector(this.plugin, this, compatibleParents).open(); }); new import_obsidian34.ButtonComponent(this.parentSelectContainer).setIcon("trash").onClick(() => this.setParent(void 0)); if (!compatibleParents.length) this.parentSelectContainer.hide(); else this.parentSelectContainer.show(); } createFrontmatterListDisplayContainer() { this.frontmatterListDisplayContainer = this.contentEl.createDiv({ cls: "field-container" }); this.frontmatterListDisplayContainer.createDiv({ text: "Frontmatter list display type", cls: "label" }); this.frontmatterListDisplayContainer.createDiv({ cls: "spacer" }); const frontmatterListDisplay = new import_obsidian34.DropdownComponent(this.frontmatterListDisplayContainer); const options2 = {}; options2["asArray"] = "display as array"; options2["asList"] = "display as indented list"; options2["undefined"] = `Plugin Default (${this.plugin.settings.frontmatterListDisplay})`; frontmatterListDisplay.addOptions(options2); switch (this.field.display) { case "asArray" /* asArray */: frontmatterListDisplay.setValue("asArray"); break; case "asList" /* asList */: frontmatterListDisplay.setValue("asList"); break; case void 0: frontmatterListDisplay.setValue("undefined"); break; } frontmatterListDisplay.onChange((value) => { switch (value) { case "asArray": this.frontmatterListDisplay = "asArray" /* asArray */; break; case "asList": this.frontmatterListDisplay = "asList" /* asList */; break; case "undefined": this.frontmatterListDisplay = void 0; break; default: this.frontmatterListDisplay = void 0; } }); if (!multiTypes.includes(this.field.type)) this.frontmatterListDisplayContainer.hide(); } createCommandContainer() { var _a, _b; const commandContainer = this.contentEl.createDiv({ cls: "field-container" }); commandContainer.createDiv({ text: "set a command for this field?", cls: "label" }); commandContainer.createDiv({ cls: "spacer" }); const addCommandToggler = new import_obsidian34.ToggleComponent(commandContainer); addCommandToggler.setValue(this.addCommand); const iconContainer = this.contentEl.createDiv({ cls: "field-container" }); this.addCommand ? iconContainer.show() : iconContainer.hide(); iconContainer.createDiv({ text: "Icon name for mobile toolbar", cls: "label" }); this.iconName = new import_obsidian34.TextComponent(iconContainer); this.iconName.inputEl.addClass("full-width"); this.iconName.inputEl.addClass("with-label"); const iconPreview = iconContainer.createDiv({ cls: "icon-preview" }); this.iconName.setValue(((_a = this.command) == null ? void 0 : _a.icon) || "command"); (0, import_obsidian34.setIcon)(iconPreview, ((_b = this.command) == null ? void 0 : _b.icon) || "command"); this.iconName.onChange((value) => { this.command.icon = value; (0, import_obsidian34.setIcon)(iconPreview, value); }); addCommandToggler.onChange((value) => { this.addCommand = value; this.addCommand ? iconContainer.show() : iconContainer.hide(); }); } setLabelStyle(label) { const fieldStyle = this.field.style || {}; fieldDecorations.forEach((style) => { const styleKey = FieldStyleKey[style]; if (!!fieldStyle[styleKey]) { label.addClass(styleKey); } else { label.removeClass(styleKey); } }); } createStyleSelectorContainer(parentNode) { const styleSelectorLabel = parentNode.createDiv({ cls: "label" }); styleSelectorLabel.setText(`Inline field style`); this.setLabelStyle(styleSelectorLabel); parentNode.createDiv({ text: "::" }); parentNode.createDiv({ cls: "spacer" }); const styleButtonsContainer = parentNode.createDiv({ cls: "style-buttons-container" }); fieldDecorations.forEach((style) => { const styleBtnContainer = styleButtonsContainer.createEl(FieldHTMLTagMap[style], { cls: "style-button-container" }); styleBtnContainer.createDiv({ cls: "style-btn-label", text: FieldStyleKey[style] }); const styleBtnToggler = new import_obsidian34.ToggleComponent(styleBtnContainer); styleBtnToggler.setValue(this.field.style ? this.field.style[FieldStyleKey[style]] : false); styleBtnToggler.onChange((v) => { const fieldStyle = this.field.style || {}; fieldStyle[FieldStyleKey[style]] = v; this.field.style = fieldStyle; this.setLabelStyle(styleSelectorLabel); }); this.decorationButtons[style] = styleBtnToggler; }); } setTypeInfo() { this.frontmatterOnlyTypeInfoContainer.replaceChildren(); if (frontmatterOnlyTypes.includes(this.field.type)) { const info = new import_obsidian34.ButtonComponent(this.frontmatterOnlyTypeInfoContainer); info.setClass("tooltip-button"); (0, import_obsidian34.setIcon)(info.buttonEl, "info"); info.setTooltip(`${this.field.type} field type are only available in the frontmatter section`); } } setType(fieldType, fieldTypeLabelContainer) { var _a; fieldTypeLabelContainer.setText(fieldType); fieldTypeLabelContainer.className = `chip ${getTagName(fieldType)}`; this.field.fileClassName = (_a = this.fileClass) == null ? void 0 : _a.name; const Field18 = buildEmptyField(plugin, this.field.fileClassName, fieldType); const settingsModal30 = getFieldSettingsModal(Field18, fieldType, plugin, parentSetting, parentSettingContainer); settingsModal30.field.name = this.namePromptComponent.getValue(); settingsModal30.open(); this.close(); return settingsModal30; } buildTypeSelectContainer() { this.typeSelectContainer.replaceChildren(); const typeSelectorContainerLabel = this.typeSelectContainer.createDiv({ cls: "label" }); typeSelectorContainerLabel.setText(`Field type:`); this.typeSelectContainer.createDiv({ cls: "spacer" }); const infoBtnContainer = this.typeSelectContainer.createDiv({ cls: "tooltip-btn" }); const info = new import_obsidian34.ButtonComponent(infoBtnContainer); info.setClass("tooltip-button"); (0, import_obsidian34.setIcon)(info.buttonEl, !(this.field.id && !this.isNew) ? "shield-alert" : "lock"); info.setTooltip(`The field type can't be modified once saved`); this.typeNameContainer = this.typeSelectContainer.createDiv({ cls: "field-type-label" }).createDiv({ cls: `chip ${getTagName(this.field.type)}` }); if (!this.field.id || this.isNew) { new import_obsidian34.ButtonComponent(this.typeSelectContainer).setButtonText("Choose a type").onClick(() => { this.typeSelector = new TypeSelector(this.plugin, this, this.typeNameContainer); this.typeSelector.open(); }).buttonEl.setAttr("id", "field-type-selector-btn"); } this.frontmatterOnlyTypeInfoContainer = this.typeSelectContainer.createDiv({ cls: "tooltip-btn" }); this.setTypeInfo(); if (this.field.type) { this.typeNameContainer.setText(this.field.type); if (multiTypes.includes(this.field.type)) { this.frontmatterListDisplayContainer.show(); } else { this.frontmatterListDisplayContainer.hide(); } } } validateFields() { return this.field.validateName( this.namePromptComponent, this.contentEl ) && this.validateOptions(); } createSaveButton(container) { const saveButton = new import_obsidian34.ButtonComponent(container); saveButton.setTooltip("Save"); saveButton.setIcon("checkmark"); saveButton.onClick(async () => { let error = !this.validateFields(); if (error) { new import_obsidian34.Notice("Fix errors before saving."); return; } ; if (this.addCommand) { this.field.command = this.command; insertIFieldCommand(this.plugin, this.command, this.field, this.field.fileClassName); } else { delete this.field.command; } if (this.frontmatterListDisplay !== void 0) { this.field.display = this.frontmatterListDisplay; } else { delete this.field.display; } this.save(); this.close(); }); } async save() { if (this.fileClass) { await this.fileClass.updateIAttribute( this.field, this.field.type, this.field.name, this.field.options, this.field.command, this.field.display, this.field.style, this.field.path ); } else { this.saved = true; const cEF = this.plugin.presetFields.filter((p) => p.id == this.field.id)[0]; const _field = cEF ? getField(cEF.id, void 0, this.plugin) : void 0; if (_field) { copyProperty(_field, this.field); this.plugin.presetFields = [...this.plugin.presetFields.filter((p) => p.id !== cEF.id), _field]; } else { this.plugin.presetFields.push(this.field); } ; copyProperty(this.initialField, this.field); if (parentSetting) copyProperty(parentSetting.field, this.field); parentSetting == null ? void 0 : parentSetting.setTextContentWithname(); incrementVersion(this.plugin); await this.plugin.saveSettings(); } } onCancel() { this.close(); } createRemovalBtn(container) { const removeButton = new import_obsidian34.ButtonComponent(container); removeButton.setIcon("trash"); removeButton.onClick(() => { const confirmModal = new import_obsidian34.Modal(this.plugin.app); confirmModal.containerEl.addClass("metadata-menu"); confirmModal.titleEl.setText("Please confirm"); confirmModal.contentEl.createDiv().setText(`Do you really want to remove this field?`); const confirmFooter = confirmModal.contentEl.createDiv({ cls: "footer-actions" }); confirmFooter.createDiv({ cls: "spacer" }); const confirmButton = new import_obsidian34.ButtonComponent(confirmFooter); confirmButton.setWarning(); confirmButton.setIcon("checkmark"); confirmButton.onClick(async () => { if (this.field) await this.removeField(); confirmModal.close(); this.close(); }); const dismissButton = new import_obsidian34.ButtonComponent(confirmFooter); dismissButton.setIcon("cross"); dismissButton.onClick(() => this.close()); confirmModal.open(); }); } async removeField() { if (this.fileClass) { if (this.field) await this.fileClass.removeIAttribute(this.field); } else { const currentExistingProperty = this.plugin.presetFields.filter((p) => p.id == this.field.id)[0]; if (currentExistingProperty) { this.plugin.presetFields.remove(currentExistingProperty); } ; await this.plugin.saveSettings(); } } createCancelButton(container) { const cancelButton = new import_obsidian34.ButtonComponent(container); cancelButton.setIcon("cross"); cancelButton.setTooltip("Cancel"); cancelButton.onClick(() => this.onCancel()); } onClose() { if (this.saved) { if (parentSettingContainer && this.saved) { Object.assign(this.field, this.initialField); if (!this.isNew && parentSetting) { parentSetting.setTextContentWithname(); } else { new FieldSetting(parentSettingContainer, this.field, this.plugin); } ; } } } }; } function openSettings(id, fileClassName, plugin, parentSetting, parentSettingContainer) { let Field18 = void 0; let type = "Input"; if (!id) { Field18 = buildEmptyField(plugin, fileClassName, type); } else { [Field18, type] = getFieldConstructor(id, fileClassName, plugin) || []; } if (Field18 && type) { const settingsModal30 = getFieldSettingsModal(Field18, type, plugin, parentSetting, parentSettingContainer); settingsModal30.open(); return settingsModal30; } } function areOptionsEqual(o1, o2) { return !!(!o1 && !o2) || !!(o1 && o2 && Object.keys(o1).every( (k) => k in o2 && typeof o1[k] === "object" ? areOptionsEqual(o1[k], o2[k]) : o1[k] === o2[k] ) && Object.keys(o2).every( (k) => k in o1 && typeof o2[k] === "object" ? areOptionsEqual(o2[k], o1[k]) : o2[k] === o1[k] )); } function areStylesEqual(s1, s2) { return !!(!s1 && !s2) || !!(s1 && s2 && Object.keys(s1).every((k) => k in s2 && s1[k] === s2[k]) && Object.keys(s2).every((k) => k in s1 && s2[k] === s1[k])); } function areCommandsEqual(c1, c2) { return !!(!c1 && !c2) || !!(c1 && c2 && c1.hotkey === c2.hotkey && c1.icon === c2.icon && c1.id === c1.id && c1.label === c2.label); } function areFieldSettingsEqualWithoutId(f1, f2) { return f1.name === f2.name && f1.type === f2.type && f1.path === f2.path && f1.display === f2.display && areOptionsEqual(f1.options, f2.options) && areStylesEqual(f1.style, f2.style) && areCommandsEqual(f1.command, f2.command); } // src/testing/tests/settingsCreation.ts var import_obsidian43 = require("obsidian"); // src/settings/MetadataMenuSettingTab.ts var import_obsidian38 = require("obsidian"); // src/fileClass/FileClassQuery.ts var import_obsidian35 = require("obsidian"); var FileClassQuery = class { constructor(name = "", id = "", query = "", fileClassName = "") { this.name = name; this.id = id; this.query = query; this.fileClassName = fileClassName; } //@ts-ignore getResults(api) { try { return new Function("dv", `return ${this.query}`)(api); } catch (error) { new import_obsidian35.Notice(` for <${this.name}>. Check your settings`); return []; } } matchFile(file) { const dataview = app.plugins.plugins.dataview; if (this.query && (dataview == null ? void 0 : dataview.settings.enableDataviewJs) && (dataview == null ? void 0 : dataview.settings.enableInlineDataviewJs)) { try { const filesPath = this.getResults(dataview.api).values.map((v) => v.file.path); return filesPath.includes(file.path); } catch (error) { return false; } } else { return false; } } static copyProperty(target, source) { target.id = source.id; target.name = source.name; target.query = source.query; target.fileClassName = source.fileClassName; } }; var FileClassQuery_default = FileClassQuery; // src/settings/FileClassQuerySettingModal.ts var import_obsidian37 = require("obsidian"); // src/settings/FileClassQuerySetting.ts var import_obsidian36 = require("obsidian"); var FileClassQuerySetting = class extends import_obsidian36.Setting { constructor(containerEl, property, plugin) { super(containerEl); this.containerEl = containerEl; this.plugin = plugin; this.fileClassQuery = property; this.setTextContentWithname(); this.addEditButton(); this.addDeleteButton(); this.addMoveUpButton(); this.settingEl.addClass("no-border"); } setTextContentWithname() { this.infoEl.textContent = ""; this.infoEl.addClass("setting-item"); const fileClassQueryContainer = this.infoEl.createDiv(); const nameContainer = fileClassQueryContainer.createEl("div", "name"); nameContainer.innerHTML = `${this.fileClassQuery.name}`; const fileClassNameContainer = fileClassQueryContainer.createEl("div"); fileClassNameContainer.innerHTML = `FileClass : ${this.fileClassQuery.fileClassName}`; const queryContainer = fileClassQueryContainer.createEl("div"); queryContainer.innerHTML = `Query : ${this.fileClassQuery.query}`; } addEditButton() { this.addButton((b) => { b.setIcon("pencil").setTooltip("Edit").onClick(() => { let modal = new FileClassQuerySettingsModal(this.plugin, this.containerEl, this, this.fileClassQuery); modal.open(); }); }); } addDeleteButton() { this.addButton((b) => { b.setIcon("trash").setTooltip("Delete").onClick(() => { var _a; const currentExistingFileClassQuery = this.plugin.initialFileClassQueries.find((p) => p.id == this.fileClassQuery.id); if (currentExistingFileClassQuery) { this.plugin.initialFileClassQueries.remove(currentExistingFileClassQuery); } ; (_a = this.settingEl.parentElement) == null ? void 0 : _a.removeChild(this.settingEl); this.plugin.saveSettings(); }); }); } addMoveUpButton() { this.addButton((b) => { b.setIcon("up-chevron-glyph").setTooltip("Move up (lower priority)").onClick(() => { const currentFileClassQueryIndex = this.plugin.initialFileClassQueries.map((fcq) => fcq.id).indexOf(this.fileClassQuery.id); if (currentFileClassQueryIndex > 0) { this.containerEl.insertBefore(this.settingEl, this.settingEl.previousElementSibling); this.plugin.initialFileClassQueries.splice(currentFileClassQueryIndex, 1); this.plugin.initialFileClassQueries.splice(currentFileClassQueryIndex - 1, 0, this.fileClassQuery); this.plugin.saveSettings(); } }); }); } }; // src/settings/FileClassQuerySettingModal.ts var FileClassQuerySettingsModal = class extends import_obsidian37.Modal { constructor(plugin, parentSettingContainer, parentSetting, fileClassQuery) { super(plugin.app); this.plugin = plugin; this.parentSettingContainer = parentSettingContainer; this.parentSetting = parentSetting; this.saved = false; this.new = true; this.initialFileClassQuery = new FileClassQuery_default(); if (fileClassQuery) { this.new = false; this.fileClassQuery = fileClassQuery; FileClassQuery_default.copyProperty(this.initialFileClassQuery, this.fileClassQuery); } else { let newId = 1; this.plugin.initialFileClassQueries.forEach((prop) => { if (parseInt(prop.id) && parseInt(prop.id) >= newId) { newId = parseInt(prop.id) + 1; } ; }); this.fileClassQuery = new FileClassQuery_default(); this.fileClassQuery.id = newId.toString(); this.initialFileClassQuery.id = newId.toString(); } ; this.containerEl.addClass("metadata-menu"); } async onOpen() { if (this.fileClassQuery.name == "") { this.titleEl.setText(`Select a fileClass and add an applicable query`); } else { this.titleEl.setText(`Manage ${this.fileClassQuery.name} settings`); } ; await this.createForm(); } onClose() { Object.assign(this.fileClassQuery, this.initialFileClassQuery); if (!this.new && this.parentSetting) { this.parentSetting.setTextContentWithname(); } else if (this.saved) { new FileClassQuerySetting(this.parentSettingContainer, this.fileClassQuery, this.plugin); } ; } createnameInputContainer(container) { container.createDiv({ cls: "label", text: `FileClass Query Name:` }); const input = new import_obsidian37.TextComponent(container); input.inputEl.addClass("with-label"); input.inputEl.addClass("full-width"); const name = this.fileClassQuery.name; input.setValue(name); input.setPlaceholder("Name of this fileClass query"); input.onChange((value) => { this.fileClassQuery.name = value; this.titleEl.setText(`Manage options for ${this.fileClassQuery.name}`); }); return input; } createFileClassSelectorContainer(container) { container.createDiv({ cls: "label", text: `Fileclass:` }); container.createDiv({ cls: "spacer" }); const select = new import_obsidian37.DropdownComponent(container); const classFilesPath = this.plugin.settings.classFilesPath; const fileClasses = this.plugin.app.vault.getFiles().filter((f) => classFilesPath && f.path.startsWith(classFilesPath)).reverse(); select.addOption("--Select a fileClass--", "--Select a fileClass--"); fileClasses.forEach((fileClass) => { const fileClassName = getFileClassNameFromPath(this.plugin.settings, fileClass.path); if (fileClassName) select.addOption(fileClassName, fileClassName); }); if (this.fileClassQuery.fileClassName) { select.setValue(this.fileClassQuery.fileClassName); } select.onChange((value) => { if (value != "--Select a fileClass--") { this.fileClassQuery.fileClassName = value; } else { this.fileClassQuery.fileClassName = ""; } }); } createQueryInputContainer(container) { container.createDiv({ text: "dataviewJS query:" }); const queryStringInputContainer = container.createDiv({ cls: "field-container" }); const queryStringInput = new import_obsidian37.TextAreaComponent(queryStringInputContainer); queryStringInput.inputEl.addClass("full-width"); queryStringInput.inputEl.rows = 4; queryStringInput.setValue(this.fileClassQuery.query); queryStringInput.onChange((value) => this.fileClassQuery.query = value); } async createForm() { const nameContainer = this.contentEl.createDiv({ cls: "field-container" }); this.createnameInputContainer(nameContainer); const fileClassSelectContainer = this.contentEl.createDiv({ cls: "field-container" }); this.createFileClassSelectorContainer(fileClassSelectContainer); const fileClassQueryContainer = this.contentEl.createDiv({ cls: "vstacked" }); this.createQueryInputContainer(fileClassQueryContainer); cleanActions(this.contentEl, ".footer-actions"); const footer = this.contentEl.createDiv({ cls: "footer-actions" }); footer.createDiv({ cls: "spacer" }); this.createSaveButton(footer); this.createCancelButton(footer); } createSaveButton(container) { const b = new import_obsidian37.ButtonComponent(container); b.setTooltip("Save"); b.setIcon("checkmark"); b.onClick(async () => { var _a; if (this.fileClassQuery.fileClassName && this.fileClassQuery.name && this.fileClassQuery.query) { this.saved = true; const currentExistingFileClassQuery = this.plugin.initialFileClassQueries.filter((p) => p.id == this.fileClassQuery.id)[0]; if (currentExistingFileClassQuery) { FileClassQuery_default.copyProperty(currentExistingFileClassQuery, this.fileClassQuery); } else { this.plugin.initialFileClassQueries.push(this.fileClassQuery); } ; FileClassQuery_default.copyProperty(this.initialFileClassQuery, this.fileClassQuery); if (this.parentSetting) FileClassQuery_default.copyProperty(this.parentSetting.fileClassQuery, this.fileClassQuery); (_a = this.parentSetting) == null ? void 0 : _a.setTextContentWithname(); this.plugin.saveSettings(); this.close(); } }); } createCancelButton(container) { const b = new import_obsidian37.ButtonComponent(container); b.setIcon("cross").setTooltip("Cancel").onClick(() => { this.saved = false; if (this.initialFileClassQuery.name != "") { Object.assign(this.fileClassQuery, this.initialFileClassQuery); } ; this.close(); }); } }; // src/settings/MetadataMenuSettingTab.ts function isMetadataMenuSettingTab(tab) { return "groups" in tab; } function isPresetFieldsSettingGroup(group) { return "addNewButton" in group; } function isFileClassSettingGroup(group) { return true; } var SettingGroup = class { constructor(tab, id, title, subTitle, withButton = false) { this.tab = tab; this.id = id; this.title = title; this.subTitle = subTitle; this.withButton = withButton; this.create(); } create() { const settingHeader = this.tab.containerEl.createEl("div"); const settingHeaderContainer = settingHeader.createEl("div", { cls: "header-container" }); const settingHeaderTextContainer = settingHeaderContainer.createEl("div", { cls: "text-container" }); settingHeaderTextContainer.createEl("h4", { text: this.title, cls: "section-header" }); if (this.subTitle) settingHeaderTextContainer.createEl("div", { text: this.subTitle, cls: "setting-item-description" }); const settingsContainer = this.tab.containerEl.createEl("div"); if (this.withButton) { const settingsContainerShowButtonContainer = settingHeaderContainer.createEl("div", { cls: "setting-item-control" }); this.settingsContainerShowButton = new import_obsidian38.ButtonComponent(settingsContainerShowButtonContainer); this.settingsContainerShowButton.buttonEl.addClass("setting-item-control"); settingsContainer.hide(); this.settingsContainerShowButton.setCta(); this.settingsContainerShowButton.setIcon("chevrons-up-down"); const toggleState = () => { if (settingsContainer.isShown()) { settingsContainer.hide(); this.settingsContainerShowButton.setIcon("chevrons-up-down"); this.settingsContainerShowButton.setCta(); } else { settingsContainer.show(); this.settingsContainerShowButton.setIcon("chevrons-down-up"); this.settingsContainerShowButton.removeCta(); } }; this.settingsContainerShowButton.onClick(() => toggleState()); } this.tab.groups.push(this); this.containerEl = settingsContainer; } }; var PresetFieldsSettingGroup = class extends SettingGroup { }; var FileClassSettingGroup = class extends SettingGroup { }; var SettingTextWithButtonComponent = class extends import_obsidian38.Setting { constructor(plugin, containerEl, name, description, placeholder, currentValues, normalizeValue) { super(containerEl); this.plugin = plugin; this.containerEl = containerEl; this.name = name; this.description = description; this.placeholder = placeholder; this.currentValues = currentValues; this.normalizeValue = normalizeValue; this.newValues = []; containerEl.addClass("metadata-menu"); const saveButton = new import_obsidian38.ButtonComponent(this.containerEl); saveButton.buttonEl.addClass("save"); saveButton.setIcon("save"); saveButton.onClick(async () => { this.plugin.settings[this.currentValues] = this.newValues; await this.plugin.saveSettings(); saveButton.removeCta(); }); this.setName(this.name).setDesc(this.description).addTextArea((text) => { text.setPlaceholder(this.placeholder).setValue(this.plugin.settings[this.currentValues].join(", ")).onChange(async (value) => { saveButton.setCta(); const values = value.split(","); this.newValues = []; values.forEach((_value) => { if (value.trim()) this.newValues.push(this.normalizeValue(_value.trim())); }); }); text.inputEl.rows = 2; text.inputEl.cols = 25; }); this.settingEl.addClass("vstacked"); this.settingEl.addClass("no-border"); this.controlEl.addClass("full-width"); this.infoEl.addClass("with-button"); const infoTextContainer = this.infoEl.createDiv({ cls: "setting-item-info-text" }); while (infoTextContainer.previousElementSibling) { infoTextContainer.prepend(this.infoEl.removeChild(infoTextContainer.previousElementSibling)); } this.infoEl.createDiv({ cls: "spacer" }); this.infoEl.appendChild(saveButton.buttonEl); } }; var ButtonDisplaySetting = class extends import_obsidian38.Setting { constructor(plugin, containerEl, name, description, value, needsReload) { super(containerEl); this.plugin = plugin; this.containerEl = containerEl; this.name = name; this.description = description; this.value = value; this.needsReload = needsReload; const reloadInfo = this.containerEl.createDiv({ cls: "settings-info-warning" }); this.setName(this.name).setDesc(this.description).addToggle((cb) => { cb.setValue(this.plugin.settings[this.value]); cb.onChange((value2) => { this.plugin.settings[this.value] = value2; this.plugin.saveSettings(); if (this.needsReload) reloadInfo.textContent = "Please reload metadata menu to apply this change"; }); }).settingEl.addClass("no-border"); } }; var MetadataMenuSettingTab = class extends import_obsidian38.PluginSettingTab { constructor(plugin) { super(plugin.app, plugin); this.groups = []; this.plugin = plugin; this.newFileClassAlias = this.plugin.settings.fileClassAlias; this.newFileClassesPath = this.plugin.settings.classFilesPath; this.newTableViewMaxRecords = this.plugin.settings.tableViewMaxRecords; this.newIcon = this.plugin.settings.fileClassIcon; this.containerEl.addClass("metadata-menu"); this.containerEl.addClass("settings"); } display() { let { containerEl } = this; containerEl.empty(); const globalSettings = new SettingGroup( this, "global-settings", "Global settings", "Global settings to apply to your whole vault", true ); const scopeReloadInfo = globalSettings.containerEl.createDiv({ cls: "settings-info-warning" }); new import_obsidian38.Setting(globalSettings.containerEl).setName("Scope").setDesc("Index fields in frontmatter only or in the whole note (if you use dataview inline fields). Indexing full notes could cause some latencies in vaults with large files").addDropdown((cb) => { cb.addOption("frontmatterOnly", "Frontmatter only"); cb.addOption("fullNote", "Full note"); cb.setValue(this.plugin.settings.frontmatterOnly ? "frontmatterOnly" : "fullNote"); cb.onChange(async (value) => { this.plugin.settings.frontmatterOnly = value === "frontmatterOnly" ? true : false; await this.plugin.saveSettings(); scopeReloadInfo.textContent = "Please reload metadata menu to apply this change"; }); }).settingEl.addClass("no-border"); new import_obsidian38.Setting(globalSettings.containerEl).setName("Display field options in context menu").setDesc("Choose to show or hide fields options in the context menu of a link or a file").addToggle((toggle) => { toggle.setValue(this.plugin.settings.displayFieldsInContextMenu); toggle.onChange(async (value) => { this.plugin.settings.displayFieldsInContextMenu = value; await this.plugin.saveSettings(); }); }).settingEl.addClass("no-border"); new SettingTextWithButtonComponent( this.plugin, globalSettings.containerEl, "Excluded folders", "Folders where preset fields and fileClass options won't be applied. Useful for templates or settings folders.", "Enter/folders/paths/, comma/separated/", "fileIndexingExcludedFolders", (item) => item.replace(/\/?$/, "/") ); new SettingTextWithButtonComponent( this.plugin, globalSettings.containerEl, "Excluded extensions", "Files with these extensions won't be indexed Useful for big files that don't contain metadata. Comma separated", "", "fileIndexingExcludedExtensions", (item) => item ); new SettingTextWithButtonComponent( this.plugin, globalSettings.containerEl, "Excluded file name patterns", "files with names matching those regex won't be indexed. Useful for very specific usecases. Comma separated ", "foo*, .md$", "fileIndexingExcludedRegex", (item) => item ); new SettingTextWithButtonComponent( this.plugin, globalSettings.containerEl, "Globally ignored fields", "Fields to be ignored by the plugin. Comma separated ", "", "globallyIgnoredFields", (item) => item ); const enableAutoComplete = new import_obsidian38.Setting(globalSettings.containerEl).setName("Autocomplete").setDesc("Activate autocomplete fields").addToggle((cb) => { cb.setValue(this.plugin.settings.isAutosuggestEnabled); cb.onChange((value) => { this.plugin.settings.isAutosuggestEnabled = value; this.plugin.saveSettings(); }); }); enableAutoComplete.settingEl.addClass("no-border"); enableAutoComplete.controlEl.addClass("full-width"); const enableAutoCalculation = new import_obsidian38.Setting(globalSettings.containerEl).setName("Auto calculation").setDesc("Activate lookups and formulas fields global auto-calculation").addToggle((cb) => { cb.setValue(this.plugin.settings.isAutoCalculationEnabled); cb.onChange((value) => { this.plugin.settings.isAutoCalculationEnabled = value; this.plugin.saveSettings(); }); }); enableAutoCalculation.settingEl.addClass("no-border"); enableAutoCalculation.controlEl.addClass("full-width"); const showIndexingStatus = new import_obsidian38.Setting(globalSettings.containerEl).setName("Fields Indexing Status").setDesc("Show fields indexing status icon in status toolbar").addToggle((cb) => { cb.setValue(this.plugin.settings.showIndexingStatusInStatusBar); cb.onChange((value) => { this.plugin.settings.showIndexingStatusInStatusBar = value; const indexStatusEl = document.querySelector(".status-bar-item.plugin-metadata-menu .index-status"); if (!value) { indexStatusEl == null ? void 0 : indexStatusEl.hide(); } else { indexStatusEl == null ? void 0 : indexStatusEl.show(); } this.plugin.saveSettings(); }); }); showIndexingStatus.settingEl.addClass("no-border"); showIndexingStatus.controlEl.addClass("full-width"); const frontmatterListDisplay = new import_obsidian38.Setting(globalSettings.containerEl).setName("Frontmatter list display").setDesc("Choose wether lists should be displayed as arrays or indented lists in frontmatter").addDropdown((cb) => { [["Array", "asArray"], ["Indented List", "asList"]].forEach(([display, value]) => { cb.addOption(value, display); }); cb.setValue(this.plugin.settings.frontmatterListDisplay || "asArray" /* asArray */); cb.onChange(async (value) => { this.plugin.settings.frontmatterListDisplay = value; await this.plugin.saveSettings(); }); }); frontmatterListDisplay.settingEl.addClass("no-border"); frontmatterListDisplay.controlEl.addClass("full-width"); new import_obsidian38.Setting(globalSettings.containerEl).setName("First day of week").setDesc("For date fields, which day the date picker's week should start with").addDropdown((cb) => { for (let i = 0; i < 2; i++) { cb.addOption(i.toString(), (0, import_obsidian38.moment)().day(i).format("dddd")); } cb.setValue(this.plugin.settings.firstDayOfWeek.toString() || "1"); cb.onChange(async (value) => { this.plugin.settings.firstDayOfWeek = parseInt(value); await this.plugin.saveSettings(); }); }).settingEl.addClass("no-border"); containerEl.createDiv({ cls: "setting-divider" }); const presetFieldsSettings = new PresetFieldsSettingGroup( this, "preset-fields-settings", "Preset Fields settings", "Manage globally predefined type and options for a field throughout your whole vault", true ); new import_obsidian38.Setting(presetFieldsSettings.containerEl).setName("Add New Field Setting").setDesc("Add a new Frontmatter property for which you want preset options.").addButton((button) => { presetFieldsSettings.addNewButton = button.setTooltip("Add New Property Manager").setButtonText("Add new").setCta().onClick(async () => openSettings("", void 0, this.plugin, void 0, this.fieldsContainer)); return presetFieldsSettings.addNewButton; }).settingEl.addClass("no-border"); this.fieldsContainer = presetFieldsSettings.containerEl.createDiv({ cls: "fields-container" }); this.plugin.presetFields.sort((a, b) => { const _a = a.path ? a.path + "_" : a.id; const _b = b.path ? b.path + "_" : b.id; return _a < _b ? -1 : 1; }).forEach((prop) => { const property = new (buildEmptyField(this.plugin, void 0))(); Object.assign(property, prop); new FieldSetting(this.fieldsContainer, property, this.plugin); }); containerEl.createDiv({ cls: "setting-divider" }); const classFilesSettings = new FileClassSettingGroup( this, "fileclass-settings", "FileClass settings", "Manage fileClass folder and alias. When a note has a fileClass defined, fileClass field properties will override global preset fields settings for the same field name", true ); const cFS = classFilesSettings; cFS.fileClassesFolderSaveButton = new import_obsidian38.ButtonComponent(classFilesSettings.containerEl); cFS.fileClassesFolderSaveButton.buttonEl.addClass("save"); cFS.fileClassesFolderSaveButton.setIcon("save"); cFS.fileClassesFolderSaveButton.onClick(async () => { this.plugin.settings.classFilesPath = this.newFileClassesPath; await this.plugin.saveSettings(); cFS.fileClassesFolderSaveButton.removeCta(); }); const path = new import_obsidian38.Setting(classFilesSettings.containerEl).setName("Class Files path").setDesc("Path to the files containing the authorized fields for a type of note").addSearch((cfs) => { cFS.fileClassPathInput = cfs; new FolderSuggest(this.plugin, cfs.inputEl); cfs.setPlaceholder("Folder").setValue(this.plugin.settings.classFilesPath || "").onChange((new_folder) => { const newPath = new_folder.endsWith("/") || !new_folder ? new_folder : new_folder + "/"; this.newFileClassesPath = newPath || null; cFS.fileClassesFolderSaveButton.setCta(); }); }); path.settingEl.addClass("no-border"); path.settingEl.addClass("narrow-title"); path.controlEl.addClass("full-width"); path.settingEl.appendChild(cFS.fileClassesFolderSaveButton.buttonEl); const aliasSaveButton = new import_obsidian38.ButtonComponent(classFilesSettings.containerEl); aliasSaveButton.buttonEl.addClass("save"); aliasSaveButton.setIcon("save"); aliasSaveButton.onClick(async () => { this.plugin.settings.fileClassAlias = this.newFileClassAlias; await this.plugin.saveSettings(); aliasSaveButton.removeCta(); }); const alias = new import_obsidian38.Setting(classFilesSettings.containerEl).setName("FileClass field alias").setDesc("Choose another name for fileClass field in frontmatter (example: Category, type, ...").addText((text) => { text.setValue(this.plugin.settings.fileClassAlias).onChange(async (value) => { this.newFileClassAlias = value || "fileClass"; aliasSaveButton.setCta(); }); }); alias.settingEl.addClass("no-border"); alias.settingEl.addClass("narrow-title"); alias.controlEl.addClass("full-width"); alias.settingEl.appendChild(aliasSaveButton.buttonEl); const global = new import_obsidian38.Setting(classFilesSettings.containerEl).setName("Global fileClass").setDesc("Choose one fileClass to be applicable to all files (even it is not present as a fileClass attribute in their frontmatter). This will override the preset Fields defined above").addSearch((cfs) => { new FileSuggest( cfs.inputEl, this.plugin, this.plugin.settings.classFilesPath || "" ); cfs.setPlaceholder("Global fileClass"); cfs.setValue( this.plugin.settings.globalFileClass ? this.plugin.settings.classFilesPath + this.plugin.settings.globalFileClass + ".md" : "" ).onChange((newPath) => { var _a; this.plugin.settings.globalFileClass = newPath ? (_a = newPath.split("\\").pop().split("/").pop()) == null ? void 0 : _a.replace(".md", "") : ""; this.plugin.saveSettings(); }); }); global.settingEl.addClass("no-border"); global.settingEl.addClass("narrow-title"); global.controlEl.addClass("full-width"); const defaultIconSave = new import_obsidian38.ButtonComponent(classFilesSettings.containerEl); defaultIconSave.buttonEl.addClass("save"); defaultIconSave.setIcon("save"); defaultIconSave.onClick(async () => { this.plugin.settings.fileClassIcon = this.newIcon; await this.plugin.saveSettings(); defaultIconSave.removeCta(); }); const iconManagerContainer = classFilesSettings.containerEl.createDiv({ cls: "icon" }); const defaultIconSetting = new import_obsidian38.Setting(classFilesSettings.containerEl).setName("Default Icon").setDesc("Choose a default icon for fileclasses from lucide.dev library").addText((cb) => { cb.setValue(this.plugin.settings.fileClassIcon || DEFAULT_SETTINGS.fileClassIcon).onChange((value) => { this.newIcon = value; (0, import_obsidian38.setIcon)(iconManagerContainer, value); defaultIconSave.setCta(); }); }); (0, import_obsidian38.setIcon)(iconManagerContainer, this.plugin.settings.fileClassIcon || DEFAULT_SETTINGS.fileClassIcon); defaultIconSetting.settingEl.appendChild(iconManagerContainer); defaultIconSetting.settingEl.appendChild(defaultIconSave.buttonEl); defaultIconSetting.settingEl.addClass("no-border"); defaultIconSetting.settingEl.addClass("narrow-title"); defaultIconSetting.controlEl.addClass("full-width"); const rowPerPageSaveButton = new import_obsidian38.ButtonComponent(classFilesSettings.containerEl); rowPerPageSaveButton.buttonEl.addClass("save"); rowPerPageSaveButton.setIcon("save"); rowPerPageSaveButton.onClick(async () => { this.plugin.settings.tableViewMaxRecords = this.newTableViewMaxRecords; await this.plugin.saveSettings(); rowPerPageSaveButton.removeCta(); }); const maxRows = new import_obsidian38.Setting(classFilesSettings.containerEl).setName("Result per page").setDesc("Number of result per page in table view").addText((text) => { text.setValue(`${this.plugin.settings.tableViewMaxRecords}`).onChange(async (value) => { this.newTableViewMaxRecords = parseInt(value || `${this.plugin.settings.tableViewMaxRecords}`); rowPerPageSaveButton.setCta(); }); }); maxRows.settingEl.addClass("no-border"); maxRows.settingEl.addClass("narrow-title"); maxRows.controlEl.addClass("full-width"); maxRows.settingEl.appendChild(rowPerPageSaveButton.buttonEl); const chooseFileClassAtFileCreation = new import_obsidian38.Setting(classFilesSettings.containerEl).setName("Add a fileclass after create").setDesc("Select a fileclass at file creation to be added to the file").addToggle((cb) => { cb.setValue(this.plugin.settings.chooseFileClassAtFileCreation); cb.onChange((value) => { this.plugin.settings.chooseFileClassAtFileCreation = value; this.plugin.saveSettings(); }); }); chooseFileClassAtFileCreation.settingEl.addClass("no-border"); chooseFileClassAtFileCreation.controlEl.addClass("full-width"); const autoInsertFieldsAtFileClassInsertion = new import_obsidian38.Setting(classFilesSettings.containerEl).setName("Insert fileClass fields").setDesc("Includes fileClass in frontmatter after fileClass choice").addToggle((cb) => { cb.setValue(this.plugin.settings.autoInsertFieldsAtFileClassInsertion); cb.onChange((value) => { this.plugin.settings.autoInsertFieldsAtFileClassInsertion = value; this.plugin.saveSettings(); }); }); autoInsertFieldsAtFileClassInsertion.settingEl.addClass("no-border"); autoInsertFieldsAtFileClassInsertion.controlEl.addClass("full-width"); const showFileClassSelectInModal = new import_obsidian38.Setting(classFilesSettings.containerEl).setName("Fileclass Select").setDesc("Show fileclass select option in note fields modals").addToggle((cb) => { cb.setValue(this.plugin.settings.showFileClassSelectInModal); cb.onChange((value) => { this.plugin.settings.showFileClassSelectInModal = value; this.plugin.saveSettings(); }); }); showFileClassSelectInModal.settingEl.addClass("no-border"); showFileClassSelectInModal.controlEl.addClass("full-width"); containerEl.createDiv({ cls: "setting-divider" }); const metadataMenuBtnSettings = new SettingGroup( this, "metadata-menu-button", "Metadata Menu button", "Show extra button to access metadata menu modal of fields", true ); [ { name: "Reading mode links", description: "Display an extra button to access metadata menu form after a link in reading mode", value: "enableLinks" }, { name: "Live preview mode", description: "Display an extra button to access metadata menu form after a link in live preview", value: "enableEditor" }, { name: "Tab header", description: "Display an extra button to access metadata menu form in the tab header", value: "enableTabHeader" }, { name: "Backlinks", description: "Display an extra button to access metadata menu form in the backlinks panel", value: "enableBacklinks" }, { name: "Search", description: "Display an extra button to access metadata menu form in the search panel", value: "enableSearch" }, { name: "File explorer", description: "Display an extra button to access metadata menu form in the file explorer", value: "enableFileExplorer", needsReload: true }, { name: "Properties", description: "Display fields buttons to access metadata forms in the property section", value: "enableProperties" } ].forEach((s) => new ButtonDisplaySetting(this.plugin, metadataMenuBtnSettings.containerEl, s.name, s.description, s.value, s.needsReload)); containerEl.createDiv({ cls: "setting-divider" }); const queryFileClassSettings = new SettingGroup( this, "fileclass-queries", "Query based FileClass settings", "Manage globally predefined type and options for a field matching this query", true ); new import_obsidian38.Setting(queryFileClassSettings.containerEl).setName("Add New Query for fileClass").setDesc("Add a new query and a FileClass that will apply to files matching this query.").addButton((button) => { return button.setTooltip("Add New fileClass query").setButtonText("Add new").setCta().onClick(async () => { let modal = new FileClassQuerySettingsModal(this.plugin, queryFileClassSettings.containerEl); modal.open(); }); }).settingEl.addClass("no-border"); this.plugin.initialFileClassQueries.forEach((query) => { const fileClassQuery = new FileClassQuery_default(); Object.assign(fileClassQuery, query); new FileClassQuerySetting(queryFileClassSettings.containerEl, fileClassQuery, this.plugin); }); } }; // src/testing/tests/settingsCreation.ts var import_promises4 = require("timers/promises"); // src/testing/runner.ts var import_obsidian42 = require("obsidian"); var import_promises3 = require("timers/promises"); // src/fileClass/views/fileClassSettingsView.ts var import_obsidian40 = require("obsidian"); // src/fileClass/views/settingsViewComponents/suggestModals.ts var import_obsidian39 = require("obsidian"); var ParentSuggestModal = class extends import_obsidian39.SuggestModal { constructor(view) { super(view.plugin.app); this.view = view; this.containerEl.setAttr("id", `${this.view.fileClass.name}-extends-suggest-modal`); } getSuggestions(query) { const fileClassesNames = [...this.view.plugin.fieldIndex.fileClassesName.keys()]; const currentName = this.view.fileClass.name; return fileClassesNames.sort().filter((name) => name !== currentName && name.toLowerCase().includes(query.toLowerCase())); } onChooseSuggestion(item, evt) { const options2 = this.view.fileClass.getFileClassOptions(); const parent = this.view.plugin.fieldIndex.fileClassesName.get(item); if (parent) { options2.parent = parent; this.view.fileClass.updateOptions(options2); } } renderSuggestion(value, el) { el.setText(value); } }; var TagSuggestModal = class extends import_obsidian39.SuggestModal { constructor(view) { super(view.plugin.app); this.view = view; this.containerEl.setAttr("id", `${this.view.fileClass.name}-tagNames-suggest-modal`); } getSuggestions(query) { const tags2 = Object.keys(this.view.plugin.app.metadataCache.getTags()); return tags2.filter((t) => t.toLowerCase().includes(query.toLowerCase())); } onChooseSuggestion(item, evt) { const options2 = this.view.fileClass.getFileClassOptions(); const tagNames = options2.tagNames || []; tagNames.push(item.replace(/^#(.*)/, "$1")); options2.tagNames = tagNames; this.view.fileClass.updateOptions(options2); } renderSuggestion(value, el) { el.setText(value); } }; var FieldSuggestModal = class extends import_obsidian39.SuggestModal { constructor(view) { super(view.plugin.app); this.view = view; this.containerEl.setAttr("id", `${this.view.fileClass.name}-excludes-suggest-modal`); } getSuggestions(query) { const fileClassName = this.view.fileClass.name; const fileClassFields = this.view.plugin.fieldIndex.fileClassesFields.get(fileClassName) || []; const excludedFields = this.view.fileClass.getFileClassOptions().excludes; return fileClassFields.filter( (fCA) => { var _a; return fCA.fileClassName !== fileClassName && ((_a = fCA.fileClassName) == null ? void 0 : _a.toLowerCase().includes(query.toLowerCase())) && !(excludedFields == null ? void 0 : excludedFields.map((attr) => attr.name).includes(fCA.name)); } ).map((fCA) => fCA.name); } onChooseSuggestion(item, evt) { const options2 = this.view.fileClass.getFileClassOptions(); const excludedFields = options2.excludes || []; const excludedField = this.view.fileClass.attributes.find((field2) => field2.name === item); if (excludedField) { excludedFields.push(excludedField); options2.excludes = excludedFields; this.view.fileClass.updateOptions(options2); } } renderSuggestion(value, el) { el.setText(value); } }; var PathSuggestModal = class extends import_obsidian39.SuggestModal { constructor(view) { super(view.plugin.app); this.view = view; this.plugin = view.plugin; this.containerEl.setAttr("id", `${this.view.fileClass.name}-filesPaths-suggest-modal`); } getSuggestions(query) { const abstractFiles = this.plugin.app.vault.getAllLoadedFiles(); const folders = []; abstractFiles.forEach((folder) => { if (folder instanceof import_obsidian39.TFolder && folder.path.toLowerCase().contains(query.toLowerCase())) { folders.push(folder); } }); return folders.map((f) => f.path); } onChooseSuggestion(item, evt) { const options2 = this.view.fileClass.getFileClassOptions(); const filesPaths = options2.filesPaths || []; filesPaths.push(item); options2.filesPaths = filesPaths; this.view.fileClass.updateOptions(options2); } renderSuggestion(value, el) { el.setText(value); } }; var BookmarksGroupSuggestModal = class extends import_obsidian39.SuggestModal { constructor(view) { super(view.plugin.app); this.view = view; this.getGroups = (items, groups = [], path = "") => { for (const item of items) { if (item.type === "group") { const subPath = `${path}${path ? "/" : ""}${item.title}`; groups.push(subPath); if (item.items) this.getGroups(item.items, groups, subPath); } } }; this.plugin = view.plugin; this.containerEl.setAttr("id", `${this.view.fileClass.name}-bookmarksGroups-suggest-modal`); } getSuggestions(query) { const bookmarks = this.plugin.fieldIndex.bookmarks; const groups = ["/"]; if (bookmarks.enabled) this.getGroups(bookmarks.instance.items, groups); return groups; } onChooseSuggestion(item, evt) { var _a; const cache = ((_a = this.plugin.app.metadataCache.getFileCache(this.view.fileClass.getClassFile())) == null ? void 0 : _a.frontmatter) || {}; const options2 = this.view.fileClass.getFileClassOptions(); const bookmarksGroups = options2.bookmarksGroups || []; bookmarksGroups.push(item); options2.bookmarksGroups = bookmarksGroups; this.view.fileClass.updateOptions(options2); } renderSuggestion(value, el) { el.setText(value); } }; // src/fileClass/views/fileClassSettingsView.ts var import_promises = require("timers/promises"); var FileClassSetting = class { constructor(container, label, toolTipText, buildOptionAndAction) { this.container = container; this.label = label; this.toolTipText = toolTipText; this.buildOptionAndAction = buildOptionAndAction; this.buildSetting(); } buildSetting() { this.container.createDiv({ text: this.label, cls: "label" }); const toolTipBtnContainer = this.container.createDiv({ cls: "tooltip-btn" }); const tooltipBtn = new import_obsidian40.ButtonComponent(toolTipBtnContainer).setIcon("help-circle").setClass("tooltip-button"); const action = this.container.createDiv({ cls: "action" }); this.buildOptionAndAction(action); const tooltip = this.container.createDiv({ cls: "tooltip-text" }); tooltip.innerHTML = this.toolTipText; tooltip.hide(); tooltipBtn.buttonEl.onmouseover = () => tooltip.show(); tooltipBtn.buttonEl.onmouseout = () => tooltip.hide(); } }; var FileClassSettingsView = class { constructor(plugin, viewContainer, fileClass) { this.viewContainer = viewContainer; this.fileClass = fileClass; this.fileClassSettings = {}; this.plugin = plugin; this.container = this.viewContainer.createDiv({ cls: "fv-settings" }); this.buildSettings(); } buildSettings() { this.fileClassOptions = this.fileClass.getFileClassOptions(); this.container.replaceChildren(); const settingsContainer = this.container.createDiv({ cls: "settings-container" }); this.fileClassSettings["limit"] = new FileClassSetting( settingsContainer, "Max records per page", "Maximum lines displayed per page in the table view", (action) => this.buildLimitComponent(action) ); this.fileClassSettings["mapWithTag"] = new FileClassSetting( settingsContainer, "Map with tag", `Bind tags with ${this.plugin.settings.fileClassAlias}
If Tag Names are empty this fileClass will be bound with the tag of same name`, (action) => this.buildMapWithTagComponent(action) ); this.fileClassSettings["icon"] = new FileClassSetting( settingsContainer, "Button Icon", "Name of the icon for the metadata menu button
(lucide.dev)", (action) => this.buildIconComponent(action) ); this.fileClassSettings["tagNames"] = new FileClassSetting( settingsContainer, "Tag Names", `Names of tags to bind this ${this.plugin.settings.fileClassAlias} with`, (action) => this.buildBindingComponent(action, "tagNames", TagSuggestModal) ); this.fileClassSettings["filesPaths"] = new FileClassSetting( settingsContainer, "Files paths", `Paths of files to bind this ${this.plugin.settings.fileClassAlias} with`, (action) => this.buildBindingComponent(action, "filesPaths", PathSuggestModal) ); this.fileClassSettings["bookmarksGroups"] = new FileClassSetting( settingsContainer, "Bookmarks groups", `Names group of bookmarked files to bind this ${this.plugin.settings.fileClassAlias} with`, (action) => this.buildBindingComponent(action, "bookmarksGroups", BookmarksGroupSuggestModal) ); this.fileClassSettings["parent"] = new FileClassSetting( settingsContainer, "Parent Fileclass", "Choose a fileClass to inherit fields from", (action) => this.buildExtendComponent(action) ); this.fileClassSettings["excludes"] = new FileClassSetting( settingsContainer, "Excluded Fields", `Names of fields to exclude from ancestor fileclasses`, (action) => this.buildExcludesComponent(action) ); this.buildSaveBtn(); this.saveBtn.removeClass("active"); } buildSaveBtn() { const footer = this.container.createDiv({ cls: "footer" }); const btnContainer = footer.createDiv({ cls: "cell" }); this.saveBtn = btnContainer.createEl("button"); (0, import_obsidian40.setIcon)(this.saveBtn, "save"); this.saveBtn.onclick = async () => { await this.fileClass.updateOptions(this.fileClassOptions); this.saveBtn.removeClass("active"); }; } buildLimitComponent(action) { const input = new import_obsidian40.TextComponent(action).setValue(`${this.fileClassOptions.limit}`).onChange((value) => { this.saveBtn.addClass("active"); this.fileClassOptions.limit = parseInt(value) || this.fileClassOptions.limit; }); input.inputEl.setAttr("id", "fileclass-settings-limit-input"); } buildMapWithTagComponent(action) { const toggler = new import_obsidian40.ToggleComponent(action); toggler.setValue(this.fileClassOptions.mapWithTag); toggler.onChange((value) => { this.saveBtn.addClass("active"); this.fileClassOptions.mapWithTag = value; }); toggler.toggleEl.setAttr("id", "fileclass-settings-mapWithTag-toggler"); } buildIconComponent(action) { const iconManagerContainer = action.createDiv({ cls: "icon-manager" }); const input = new import_obsidian40.TextComponent(iconManagerContainer); const iconContainer = iconManagerContainer.createDiv({}); input.setValue(this.fileClassOptions.icon); (0, import_obsidian40.setIcon)(iconContainer, this.fileClassOptions.icon); input.onChange((value) => { this.saveBtn.addClass("active"); this.fileClassOptions.icon = value; (0, import_obsidian40.setIcon)(iconContainer, this.fileClassOptions.icon); }); input.inputEl.setAttr("id", "fileclass-settings-icon-input"); } buildBindingComponent(action, setting, suggestModal) { const itemsContainer = action.createDiv({ cls: "items" }); const boundItemsNames = this.fileClassOptions[setting]; boundItemsNames == null ? void 0 : boundItemsNames.forEach((item) => { const itemContainer = itemsContainer.createDiv({ cls: "item chip", text: item }); new import_obsidian40.ButtonComponent(itemContainer).setIcon("x-circle").setClass("item-remove").onClick(async () => { boundItemsNames == null ? void 0 : boundItemsNames.remove(item); await this.fileClass.updateOptions(this.fileClassOptions); }); }); const addBtn = itemsContainer.createEl("button", { cls: "item add" }); addBtn.setAttr("id", `fileclass-setting-${setting}-addBtn`); (0, import_obsidian40.setIcon)(addBtn, "plus-circle"); addBtn.onclick = () => { new suggestModal(this).open(); }; } buildExcludesComponent(action) { var _a; const fieldsContainer = action.createDiv({ cls: "items" }); (_a = this.fileClassOptions.excludes) == null ? void 0 : _a.forEach((field2) => { const fieldontainer = fieldsContainer.createDiv({ cls: "item chip", text: field2.name }); new import_obsidian40.ButtonComponent(fieldontainer).setIcon("x-circle").setClass("item-remove").onClick(async () => { var _a2; const excludedFields = (_a2 = this.fileClassOptions.excludes) == null ? void 0 : _a2.filter((attr) => attr.name !== field2.name); this.fileClassOptions.excludes = excludedFields; await this.fileClass.updateOptions(this.fileClassOptions); }); }); const fieldAddBtn = fieldsContainer.createEl("button", { cls: "item" }); fieldAddBtn.setAttr("id", `fileclass-setting-excludes-addBtn`); (0, import_obsidian40.setIcon)(fieldAddBtn, "plus-circle"); fieldAddBtn.onclick = () => { new FieldSuggestModal(this).open(); }; } buildExtendComponent(action) { var _a; const parentManagerContainer = action.createDiv({ cls: "items" }); const parentLinkContainer = parentManagerContainer.createDiv({ cls: "item" }); const parent = this.fileClassOptions.parent; if (parent) { const path = this.fileClass.getClassFile().path; const component = this.plugin; import_obsidian40.MarkdownRenderer.render(this.plugin.app, `[[${parent.name}]]`, parentLinkContainer, path, component); (_a = parentLinkContainer.querySelector("a.internal-link")) == null ? void 0 : _a.addEventListener("click", (e) => { var _a2; this.plugin.app.workspace.openLinkText( //@ts-ignore (_a2 = e.target.getAttr("data-href").split("/").last()) == null ? void 0 : _a2.replace(/(.*).md/, "$1"), path, //@ts-ignore "tab" ); }); } parentManagerContainer.createDiv({ cls: "item spacer" }); if (parent) { const parentRemoveBtn = parentManagerContainer.createEl("button", { cls: "item" }); (0, import_obsidian40.setIcon)(parentRemoveBtn, "trash"); parentRemoveBtn.onclick = async () => { delete this.fileClassOptions.parent; await this.fileClass.updateOptions(this.fileClassOptions); }; } const parentChangeBtn = parentManagerContainer.createEl("button", { cls: "item right-align" }); parentChangeBtn.setAttr("id", `fileclass-setting-extends-addBtn`); (0, import_obsidian40.setIcon)(parentChangeBtn, "edit"); parentChangeBtn.onclick = () => { new ParentSuggestModal(this).open(); }; } }; async function testFileClassSettingsView(plugin, fileClass, data, speed = 100) { const runner = plugin.testRunner; const fCView = plugin.app.workspace.getActiveViewOfType(FileClassView); if (!fCView || !fCView.settingsView) return runner.log("ERROR", `${fileClass.name} view didn't open`); const settingsMenuHeader = fCView.containerEl.querySelector("#settingsOption"); if (!settingsMenuHeader) return runner.log("ERROR", `${fileClass.name} settings menu not found`); settingsMenuHeader.click(); await (0, import_promises.setTimeout)(speed); const container = fCView.settingsView.container; const selectChoices = async (collection) => { const items = Array.isArray(data[collection]) ? data[collection] : data[collection] !== null ? [data[collection]] : []; if (!items.length) return; const addBtn = container.querySelector(`#fileclass-setting-${collection}-addBtn`); if (!addBtn || !(addBtn instanceof HTMLButtonElement)) return runner.log("ERROR", `add ${collection} button not found`); for (const item of items) { addBtn.click(); await (0, import_promises.setTimeout)(speed); const choices = document.querySelectorAll(`#${fileClass.name}-${collection}-suggest-modal .suggestion-item`); for (const choice of choices) { if (choice instanceof HTMLDivElement && choice.innerText.replace(/^#(.*)/, "$1") === item) { choice.click(); await (0, import_promises.setTimeout)(50); } } } }; if ("limit" in data) { const input = container.querySelector("#fileclass-settings-limit-input"); if (!input) throw Error("Limit input not found"); input.value = data.limit; input.dispatchEvent(new Event("input")); } if ("mapWithTag" in data && data.mapWithTag) { const toggle = container.querySelector("#fileclass-settings-mapWithTag-toggler"); if (!toggle) throw Error("Map with tag toggler not found"); toggle.click(); } if ("icon" in data) { const input = container.querySelector("#fileclass-settings-icon-input"); if (!input) throw Error("Icon input not found"); input.value = data.icon; input.dispatchEvent(new Event("input")); } fCView.settingsView.saveBtn.click(); await (0, import_promises.setTimeout)(50); await selectChoices("tagNames"); await selectChoices("bookmarksGroups"); await selectChoices("filesPaths"); await selectChoices("extends"); await testFileClassFieldsView(plugin, fCView.fileClass, data, speed); await selectChoices("excludes"); } // src/testing/tests/fileclassCreation.ts var import_promises2 = require("timers/promises"); var fileClassFolder = "Fileclasses"; var fileclassFixtures = "__fixtures__/fileClasses"; async function testFileClassesCreation(plugin, speed = 100) { const tab = await openPluginSettings(plugin); const fileClassSettings = tab.groups.find((g) => g.id === "fileclass-settings"); if (!fileClassSettings || !isFileClassSettingGroup(fileClassSettings)) return plugin.testRunner.log("ERROR", "Fileclass setting group is undefined"); await (0, import_promises2.setTimeout)(speed); fileClassSettings.settingsContainerShowButton.buttonEl.click(); plugin.testRunner.insertInTextComponent(fileClassSettings.fileClassPathInput, fileClassFolder); fileClassSettings.fileClassesFolderSaveButton.buttonEl.click(); plugin.app.setting.close(); const fileclasses = plugin.app.vault.getFiles().filter((f) => { var _a; return ((_a = f.parent) == null ? void 0 : _a.path) === fileclassFixtures; }).sort((f1, f2) => f1.name < f2.basename ? -1 : 1); const addFileClassBtn = document.querySelector(".fileClass-add-button"); if (!addFileClassBtn) return plugin.testRunner.log("ERROR", "Fileclass add button not found"); for (const fileclass of fileclasses) { await testCreateFileClass(plugin, addFileClassBtn, fileclass, speed); } } async function testCreateFileClass(plugin, addBtn, fileClassDataFile, speed = 100) { var _a; const fileClassName = fileClassDataFile.basename; addBtn.click(); const modal = document.querySelector("#add-new-fileclass-modal"); if (!modal) return plugin.testRunner.log("ERROR", "Add new fileclass modal not found"); const input = modal.querySelector("#fileclass-name-input"); if (!input) return plugin.testRunner.log("ERROR", "fileclass name input not found"); plugin.testRunner.insertInInputEl(input, fileClassDataFile.basename); await (0, import_promises2.setTimeout)(50); const saveBtn = modal.querySelector("#new-fileclass-confirm-btn"); saveBtn.dispatchEvent(new Event("click")); modal.querySelector(".modal-close-button").click(); await (0, import_promises2.setTimeout)(50); const fileClass = plugin.fieldIndex.fileClassesName.get(fileClassName); if (!fileClass) return plugin.testRunner.log("ERROR", `${fileClassName} wasn't create or indexed`); await testFileClassViewNavigation(plugin, fileClass, speed); const data = (_a = plugin.app.metadataCache.getFileCache(fileClassDataFile)) == null ? void 0 : _a.frontmatter; if (!data) return plugin.testRunner.log("ERROR", `${fileClassDataFile.basename} fixture data not found`); await testFileClassSettingsView(plugin, fileClass, data, speed); } // src/testing/tests/fieldsModal.ts var import_obsidian41 = require("obsidian"); var testFilePath = "Folder3/test3_1_fileclass_frontmatter.md"; var numberTest = { name: "push-ups", value: 10 }; var inputTest = { name: "calories", value: "test" }; async function testValueModification(plugin, speed = 100) { await testMetadataMenuButton(plugin, speed); } async function testMetadataMenuButton(plugin, speed = 100) { const test3_1 = plugin.app.vault.getAbstractFileByPath(testFilePath); if (!test3_1) return plugin.testRunner.log("ERROR", testFilePath + " not found"); await plugin.app.workspace.openLinkText(test3_1.path, test3_1.path); const leaf = plugin.app.workspace.getActiveViewOfType(import_obsidian41.MarkdownView); if (!(leaf == null ? void 0 : leaf.file) || !(leaf.file instanceof import_obsidian41.TFile) || leaf.file.path !== testFilePath) return plugin.testRunner.log("ERROR", "Active pane isn't test3_1"); const addFileClassCommand = plugin.app.commands.commands["metadata-menu:add_fileclass_to_file"]; if (!addFileClassCommand || !addFileClassCommand.checkCallback) return plugin.testRunner.log("ERROR", "AddFileClass command not found"); addFileClassCommand.checkCallback(false); const fileClassName = "Fileclass1"; const choice = document.querySelector(`#fileclass-${fileClassName}-add-choice`); if (!choice) return plugin.testRunner.log("ERROR", "Fileclass choice not found"); plugin.testRunner.planActionAfterMetadataCacheResolution(async () => { await checkFileClass(plugin, leaf.file, fileClassName, speed); }); choice.click(); } async function checkFileClass(plugin, file, fileClassName, speed = 100) { var _a; const frontmatter = (_a = plugin.app.metadataCache.getFileCache(file)) == null ? void 0 : _a.frontmatter; if ((frontmatter == null ? void 0 : frontmatter["fileClass"]) === fileClassName) plugin.testRunner.log("SUCCESS", "Adding FileClass to file"); plugin.testRunner.planActionAfterButtonBuilt( file.path.replace(/\.md$/, ""), "tabHeader", fileClassName, async () => { await openFieldsModal(plugin, file, speed); } ); } async function openFieldsModal(plugin, file, speed = 100) { const tab = document.querySelector(".workspace-tab-header[aria-label=test3_1_fileclass_frontmatter]"); if (!tab) return plugin.testRunner.log("ERROR", "tab not found"); const button = tab.querySelector("a.metadata-menu.fileclass-icon"); if (!button) return plugin.testRunner.log("ERROR", "button not found"); plugin.testRunner.planActionAfterFieldsModalBuilt( file, async () => { await insertMissingFields2(plugin, file, speed); } ); button.click(); } async function insertMissingFields2(plugin, file, speed = 100) { const modal = document.querySelector(".modal-container.metadata-menu.note-fields-modal"); if (!modal) return plugin.testRunner.log("ERROR", "Fields Modal not found"); const insertFieldsInFrontmatterBtn = modal.querySelector("button.in-frontmatter-btn"); if (!insertFieldsInFrontmatterBtn) return plugin.testRunner.log("ERROR", "Insert missing fields in frontmatter button not found"); plugin.testRunner.planActionAfterFieldsModalBuilt(file, () => { plugin.testRunner.planActionAfterFieldsModalBuilt(file, async () => { await testNumberFieldAction(plugin, modal, speed); plugin.testRunner.nextActionAfterFieldsModal = () => { }; plugin.testRunner.waitingForModalForFilePath = void 0; }, false); }, false); insertFieldsInFrontmatterBtn.click(); } async function testNumberFieldAction(plugin, modal, speed = 100) { var _a; const numberField = (_a = plugin.fieldIndex.filesFields.get(testFilePath)) == null ? void 0 : _a.find((f) => f.name === numberTest.name); if (!numberField) return plugin.testRunner.log("ERROR", `${numberTest.name} field not found`); const incrementBtn = modal.querySelector(`#field_${numberField.id}_increase`); if (!incrementBtn) return plugin.testRunner.log("ERROR", `${numberField.name} increment button not found`); plugin.testRunner.planActionAfterFieldIndex(() => { getNumberFieldResultAndTestInputField(plugin, numberField, modal, speed); }); incrementBtn.click(); } async function getNumberFieldResultAndTestInputField(plugin, numberField, modal, speed = 100) { var _a, _b; const file = plugin.app.vault.getAbstractFileByPath(testFilePath); if (!(file instanceof import_obsidian41.TFile)) return plugin.testRunner.log("ERROR", testFilePath + " file not found"); const note = await Note.buildNote(plugin, file); const test = ((_a = note.existingFields.find((eF) => eF.field.id === numberField.id)) == null ? void 0 : _a.value) === numberField.options.step; plugin.testRunner.log(test ? "SUCCESS" : "ERROR", "Number field action from fields modal"); const input = (_b = plugin.fieldIndex.filesFields.get(testFilePath)) == null ? void 0 : _b.find((f) => f.name === inputTest.name); if (!input) return plugin.testRunner.log("ERROR", `${inputTest.name} field not found`); const updateBtn = modal.querySelector(`#field_${input.id}_update`); if (!updateBtn) return plugin.testRunner.log("ERROR", `${input.name} increment button not found`); plugin.testRunner.planActionAfterFieldUpdateModalBuilt(input.id, (modal2) => { testInputModal(plugin, input, modal2, speed); }); updateBtn.click(); } async function testInputModal(plugin, input, inputModal, speed = 100) { const modal = document.querySelector(`#field_${input.id}_update_modal`); if (!modal) return plugin.testRunner.log("ERROR", `${input.name} update modal not found`); const textArea = modal.querySelector("textarea"); if (!textArea) return plugin.testRunner.log("ERROR", `${input.name} text area not found`); plugin.testRunner.insertInInputEl(textArea, inputTest.value); plugin.testRunner.planActionAfterFieldIndex(() => { testInputUpdate(plugin, input, speed); }); inputModal.managedField.save(); inputModal.close(); } async function testInputUpdate(plugin, input, speed = 100) { var _a; const file = plugin.app.vault.getAbstractFileByPath(testFilePath); if (!(file instanceof import_obsidian41.TFile)) return plugin.testRunner.log("ERROR", testFilePath + " file not found"); const note = await Note.buildNote(plugin, file); const test = ((_a = note.existingFields.find((eF) => eF.field.id === input.id)) == null ? void 0 : _a.value) === inputTest.value; plugin.testRunner.log(test ? "SUCCESS" : "ERROR", "Input field action from fields modal"); const modal = document.querySelector(".modal-container.metadata-menu.note-fields-modal"); if (!modal) return plugin.testRunner.log("ERROR", "Fields Modal not found"); modal.querySelector(".modal-close-button").click(); } // src/testing/runner.ts var TestRunner = class extends import_obsidian42.Component { constructor(plugin) { super(); this.plugin = plugin; this.speed = 10; this.defaultAction = () => { }; this.waitingForMetadata = false; this.waitingForIndexing = false; this.waitingForButtonView = null; this.waitingForButtonFileclass = void 0; this.waitingForButtonDest = void 0; this.nextActionAfterIndex = this.defaultAction; this.nextActionAfterCache = this.defaultAction; this.nextActionAfterButton = this.defaultAction; this.nextActionAfterFieldsModal = this.defaultAction; this.nextActionAfterFieldUpdateModal = this.defaultAction; this.resetAfterIndexAction = true; this.resetAfterCacheAction = true; this.resetAfterButtonAction = true; this.resetAfterFieldModalAction = true; this.resetAfterFieldUpdateModalAction = true; this.modals = []; this.fieldsUpdateModals = []; this.vault = plugin.app.vault; this.index = plugin.fieldIndex; this.metadataCache = plugin.app.metadataCache; this.workspace = plugin.app.workspace; } onload() { this.registerEvent( this.metadataCache.on("metadata-menu:indexed", async () => { if (this.waitingForIndexing) { await this.nextActionAfterIndex(); if (this.resetAfterIndexAction) { this.waitingForIndexing = false; this.nextActionAfterIndex = this.defaultAction; } } }) ); this.registerEvent( this.metadataCache.on("resolved", async () => { if (this.waitingForMetadata) { await this.nextActionAfterCache(); if (this.resetAfterCacheAction) { this.waitingForMetadata = false; this.nextActionAfterCache = this.defaultAction; } } }) ); this.registerEvent( this.workspace.on("metadata-menu:button-built", async (destPath, viewTypeName, fileClassName) => { if (this.waitingForButtonDest === destPath && this.waitingForButtonFileclass === fileClassName && this.waitingForButtonView === viewTypeName) { await this.nextActionAfterButton(); if (this.resetAfterButtonAction) { this.waitingForButtonDest = void 0; this.waitingForButtonFileclass = void 0; this.waitingForButtonView = null; this.nextActionAfterButton = this.defaultAction; } } }) ); this.registerEvent( this.workspace.on("metadata-menu:fields-modal-built", async (modal) => { if (this.waitingForModalForFilePath === modal.file.path) { this.modals.push(modal); await this.nextActionAfterFieldsModal(); if (this.resetAfterFieldModalAction) { this.waitingForModalForFilePath = void 0; this.nextActionAfterFieldsModal = this.defaultAction; } } }) ); this.registerEvent( this.workspace.on("metadata-menu:field-update-modal-built", async (modal) => { if (this.waitingForModalForFieldId === modal.managedField.id) { this.fieldsUpdateModals.push(modal); await this.nextActionAfterFieldUpdateModal(modal); if (this.resetAfterFieldUpdateModalAction) { this.waitingForModalForFieldId = void 0; this.nextActionAfterFieldUpdateModal = this.defaultAction; } } }) ); } async run() { await this.clean(); await testPresetFieldsCreation(this.plugin, this.speed); await testFileClassesCreation(this.plugin, this.speed); await testValueModification(this.plugin, this.speed); } async clean() { for (const leaf of this.workspace.getLeavesOfType("markdown")) { leaf.detach(); } this.plugin.presetFields = []; this.plugin.settings.classFilesPath = ""; await this.plugin.saveSettings(); const fileClassFiles = this.vault.getFiles().filter((f) => { var _a; return ((_a = f.parent) == null ? void 0 : _a.path) === fileClassFolder; }); const testFile = this.vault.getAbstractFileByPath(testFilePath); if (!(testFile instanceof import_obsidian42.TFile)) return this.plugin.testRunner.log("ERROR", `Didn't find ${testFilePath}`); await this.plugin.app.vault.modify(testFile, ""); for (const fC of fileClassFiles) await this.vault.adapter.remove(fC.path); await this.index.fullIndex(true); this.metadataCache.cleanupDeletedCache(); console.log("%c [CLEANED]", "color: blue"); } planActionAfterFieldIndex(action, reset = true) { this.nextActionAfterIndex = action; this.waitingForIndexing = true; this.resetAfterIndexAction = reset; } planActionAfterMetadataCacheResolution(action, reset = true) { this.nextActionAfterCache = action; this.waitingForMetadata = true; this.resetAfterCacheAction = reset; } planActionAfterButtonBuilt(destPath, viewTypeName, fileClassName, action, reset = true) { this.nextActionAfterButton = action; this.waitingForButtonDest = destPath; this.waitingForButtonFileclass = fileClassName; this.waitingForButtonView = viewTypeName; this.resetAfterButtonAction = reset; } planActionAfterFieldsModalBuilt(file, action, reset = true) { this.nextActionAfterFieldsModal = action; this.waitingForModalForFilePath = file.path; this.resetAfterFieldModalAction = reset; } planActionAfterFieldUpdateModalBuilt(id, action, reset = true) { this.nextActionAfterFieldUpdateModal = action; this.waitingForModalForFieldId = id; this.resetAfterFieldUpdateModalAction = reset; } log(status, output) { if (status === "SUCCESS") { console.log("%c [SUCCESS]: " + output, "background: #222; color: #bada55"); } else { console.log("%c [ERROR]: " + output, "background: red; color: white"); } } insertInInputEl(inputEl, value) { inputEl.value = value; inputEl.dispatchEvent(new Event("input")); } insertInTextComponent(input, value) { this.insertInInputEl(input.inputEl, value); } selectInDropDownComponent(select, value) { select.selectEl.value = value; select.selectEl.dispatchEvent(new Event("change")); } onunload() { for (const modal of this.modals) { modal.close(); } } }; async function openPluginSettings(plugin, speed = 100) { const app2 = plugin.app; const setting = app2.setting; await (0, import_promises3.setTimeout)(speed); setting.open(); await (0, import_promises3.setTimeout)(speed); const mdmSettingTab = setting.pluginTabs.find((p) => p.id === "metadata-menu"); if (!mdmSettingTab || !isMetadataMenuSettingTab(mdmSettingTab)) throw Error("Metadatamenu setting tab is undefined"); mdmSettingTab.navEl.click(); plugin.testRunner.log("SUCCESS", "openSettingTab"); await (0, import_promises3.setTimeout)(speed); return mdmSettingTab; } // src/testing/tests/settingsCreation.ts function getPresetFields(plugin, speed = 100) { var _a, _b; const presetFieldsFile = plugin.app.vault.getAbstractFileByPath("__fixtures__/settings/presetFields.md"); if (!presetFieldsFile || !(presetFieldsFile instanceof import_obsidian43.TFile)) return plugin.testRunner.log("ERROR", "Couldn't find preset fields File settings"); const fields = ((_b = (_a = plugin.app.metadataCache.getFileCache(presetFieldsFile)) == null ? void 0 : _a.frontmatter) == null ? void 0 : _b["fields"]) || []; return fields; } async function testPresetFieldsCreation(plugin, speed = 100) { const tab = await openPluginSettings(plugin, speed); const presetfields = tab.groups.find((g) => g.id === "preset-fields-settings"); if (!presetfields || !isPresetFieldsSettingGroup(presetfields)) return plugin.testRunner.log("ERROR", "Preset fields setting is undefined"); await (0, import_promises4.setTimeout)(speed); presetfields.settingsContainerShowButton.buttonEl.click(); plugin.testRunner.log("SUCCESS", "Opening preset fields"); const fields = getPresetFields(plugin); if (!fields) return plugin.testRunner.log("ERROR", "Preset fields not found"); for (const field2 of fields) { field2.plugin = plugin; await enterFieldSettings(field2, tab.fieldsContainer, void 0, speed); } plugin.app.setting.close(); return; } async function enterFieldSettings(field2, container, fileClass, speed = 100) { var _a, _b, _c; const plugin = field2.plugin; const fieldModal = openSettings("", fileClass == null ? void 0 : fileClass.name, field2.plugin, void 0, container); if (!fieldModal) return plugin.testRunner.log("ERROR", "Couldn't build new field modal"); await (0, import_promises4.setTimeout)(speed); fieldModal.namePromptComponent.setValue(field2.name); await (0, import_promises4.setTimeout)(speed); const typeBtn = fieldModal.containerEl.querySelector("#field-type-selector-btn"); if (!typeBtn) return plugin.testRunner.log("ERROR", "Type selector button not found"); typeBtn.click(); fieldModal.typeSelector.open(); await (0, import_promises4.setTimeout)(speed); const type = fieldModal.typeSelector.resultContainerEl.querySelector(`.field-type-${field2.type}`); if (!type) return plugin.testRunner.log("ERROR", `${type} type not found in type selector modal`); fieldModal.typeSelector.close(); fieldModal.close(); const newTypeFieldModal = fieldModal.setType(field2.type, fieldModal.typeNameContainer); const _field = newTypeFieldModal.field; if (field2.style && isFieldStyle(field2.style)) { for (const decoration of Object.keys(field2.style)) { for (const style of fieldDecorations) { if (style && FieldStyleLabel[decoration] === style) { (_a = newTypeFieldModal.decorationButtons[style]) == null ? void 0 : _a.toggleEl.click(); } } } } await getFieldSettingsTest(newTypeFieldModal, field2, speed = 100); await newTypeFieldModal.save(); newTypeFieldModal.close(); let savedField = void 0; if (_field.fileClassName) { const fileClass2 = plugin.fieldIndex.fileClassesName.get(_field.fileClassName); if (!fileClass2) return plugin.testRunner.log("ERROR", `${_field.fileClassName} not found in index`); const file = fileClass2.getClassFile(); savedField = (((_c = (_b = plugin.app.metadataCache.getFileCache(file)) == null ? void 0 : _b.frontmatter) == null ? void 0 : _c.fields) || []).find((f) => f.name === _field.name && f.path === _field.path); } else { const presetFields = (await fieldModal.plugin.loadData()).presetFields; savedField = presetFields.find((f) => f.name === _field.name); } if (!savedField) return plugin.testRunner.log("ERROR", `${_field.name} not saved`); const STATUS = areFieldSettingsEqualWithoutId(savedField, field2) ? "SUCCESS" : "ERROR"; plugin.testRunner.log(STATUS, `Field ${_field.name} creation`); } // src/fileClass/views/fileClassFieldsView.ts var FileClassFieldSetting = class { constructor(container, fileClass, fileClassAttribute, plugin) { this.container = container; this.fileClass = fileClass; this.fileClassAttribute = fileClassAttribute; this.plugin = plugin; this.buildSetting(); } buildSetting() { const fCA = this.fileClassAttribute; const fieldNameContainer = this.container.createDiv({ cls: "name-container" }); const level = !fCA.path ? 0 : fCA.path.split("____").length; for (let i = 0; i < level; i++) { const indentation = fieldNameContainer.createDiv({ cls: "indentation" }); if (i === level - 1) { (0, import_obsidian44.setIcon)(indentation, "corner-down-right"); } } fieldNameContainer.createEl("span", { text: fCA.name, cls: "title" }); const typeContainer = this.container.createDiv({ cls: "type-container" }); const chip = typeContainer.createDiv({ cls: `chip ${getTagName(fCA.type)}` }); chip.setText(fCA.type); const fieldButtonsContainer = this.container.createDiv({ cls: "buttons-container" }); this.addEditButton(fieldButtonsContainer); this.addDeleteButton(fieldButtonsContainer); this.addMoveBtn(fieldButtonsContainer, "asc", this.fileClassAttribute.id); this.addMoveBtn(fieldButtonsContainer, "desc", this.fileClassAttribute.id); const fieldOptionsContainer = this.container.createDiv({ cls: "options-container" }); fieldOptionsContainer.createEl("span", { cls: "description", text: `${fCA.getOptionsString(this.plugin)}` }); } addEditButton(container) { const btn = new import_obsidian44.ButtonComponent(container); btn.setIcon("pencil"); btn.setTooltip("Edit"); btn.onClick(() => openSettings(this.fileClassAttribute.id, this.fileClass.name, this.plugin)); } addDeleteButton(container) { const btn = new import_obsidian44.ButtonComponent(container); btn.setIcon("trash"); btn.setTooltip("Delete"); btn.setClass("cell"); btn.onClick(() => { const confirmModal = new import_obsidian44.Modal(this.plugin.app); confirmModal.containerEl.addClass("metadata-menu"); confirmModal.titleEl.setText("Please confirm"); confirmModal.contentEl.createDiv().setText(`Do you really want to remove this field?`); const confirmFooter = confirmModal.contentEl.createDiv({ cls: "footer-actions" }); confirmFooter.createDiv({ cls: "spacer" }); const confirmButton = new import_obsidian44.ButtonComponent(confirmFooter); confirmButton.setWarning(); confirmButton.setIcon("checkmark"); confirmButton.onClick(async () => { removeFileClassAttributeWithId(this.plugin, this.fileClass, this.fileClassAttribute.id); confirmModal.close(); }); const dismissButton = new import_obsidian44.ButtonComponent(confirmFooter); dismissButton.setIcon("cross"); dismissButton.onClick(() => confirmModal.close()); confirmModal.open(); }); } addMoveBtn(container, dir, id) { const btn = new import_obsidian44.ButtonComponent(container); btn.setIcon(dir === "asc" ? "chevron-up" : "chevron-down"); btn.setTooltip(dir === "asc" ? "Move up" : "Move down"); btn.setClass("cell"); btn.onClick(() => { this.fileClass.moveField(id, dir === "asc" ? "upwards" : "downwards"); }); } }; var FileClassFieldsView = class { constructor(plugin, viewContainer, fileClass) { this.viewContainer = viewContainer; this.fileClass = fileClass; this.plugin = plugin; this.container = this.viewContainer.createDiv({ cls: "fv-fields" }); this.buildSettings(); } builAddBtn() { const footer = this.container.createDiv({ cls: "footer" }); const btnContainer = footer.createDiv({ cls: "cell" }); const addBtn = btnContainer.createEl("button"); (0, import_obsidian44.setIcon)(addBtn, "list-plus"); addBtn.onclick = async () => { openSettings("", this.fileClass.name, this.plugin); }; } buildSettings() { this.container.replaceChildren(); const fieldsContainer = this.container.createDiv({ cls: "fields-container" }); const sortedAttributes = buildSortedAttributes(this.plugin, this.fileClass); sortedAttributes.forEach((attribute) => { new FileClassFieldSetting(fieldsContainer, this.fileClass, attribute, this.plugin); }); this.builAddBtn(); } }; async function testFileClassFieldsView(plugin, fileClass, data, speed = 100) { const fCView = plugin.app.workspace.getActiveViewOfType(FileClassView); if (!fCView || !fCView.fieldsView) return plugin.testRunner.log("ERROR", `${fileClass.name} view didn't open`); openTab2(fCView, "fields", speed); for (const fieldData of data.fields) { const field2 = new (buildEmptyField(plugin, fileClass.name))(); Object.assign(field2, fieldData); await enterFieldSettings(field2, void 0, fileClass); } } // src/fileClass/views/fileClassTableView.ts var import_obsidian54 = require("obsidian"); // src/fileClass/views/tableViewComponents/FieldComponent.ts var import_obsidian50 = require("obsidian"); // src/fileClass/views/tableViewComponents/RowSorterComponent.ts var import_obsidian46 = require("obsidian"); // src/fileClass/views/tableViewComponents/OptionsPriorityModal.ts var import_obsidian45 = require("obsidian"); var OptionsPriorityModal = class extends import_obsidian45.Modal { constructor(plugin, fileClassFile, field2, parentFieldSet, rowSorterComponent) { var _a; super(plugin.app); this.plugin = plugin; this.fileClassFile = fileClassFile; this.field = field2; this.parentFieldSet = parentFieldSet; this.rowSorterComponent = rowSorterComponent; this.titleEl.setText("Set a custom order by moving the values"); this.containerEl.addClass("metadata-menu"); this.initialOrder = ((_a = this.rowSorterComponent.customOrder) == null ? void 0 : _a.length) ? this.rowSorterComponent.customOrder : this.getOptions(); this.orderedOptions = [...this.initialOrder]; this.optionsContainer = this.contentEl.createDiv({}); cleanActions(this.containerEl, ".footer-actions"); const footerActionsContainer = this.containerEl.createDiv({ cls: "footer-actions" }); this.buildFooterActions(footerActionsContainer); } onOpen() { this.buildOrderedOptions(); } getOptions() { if (this.field === "file") { return []; } else { const field2 = this.field; switch (field2.type) { case "Boolean": { return ["true", "false"]; } case "Multi": case "Select": return getOptionsList(field2); case "MultiFile": case "File": { const sortingMethod = new Function("a", "b", `return ${field2.options.customSorting}`) || function(a, b) { return a.basename < b.basename ? -1 : 1; }; try { return getFiles(field2).sort(sortingMethod).map((item) => item.basename.trim().replace(/\[\[|\]\]/g, "")); } catch (error) { return []; } } case "Lookup": { const _values = [...this.plugin.fieldIndex.fileLookupFieldLastValue.entries()].filter(([fieldId, lookupFiles]) => { return fieldId.endsWith(`__related__${this.parentFieldSet.fileClass.name}___${field2.name}`) && lookupFiles !== ""; }).map(([fieldId, lookupFiles]) => lookupFiles).join(","); return [...new Set( _values.split(",").map((item) => item.trim().replace(/\[\[|\]\]/g, "")) )]; } default: return []; } } } renderOption(option, index) { const optionContainer = this.optionsContainer.createDiv({ cls: "suggestion-item value-container" }); const swapElements = (array, index1, index2) => { array[index1] = array.splice(index2, 1, array[index1])[0]; }; const buildPrioBtn = (direction) => { const btn = new import_obsidian45.ButtonComponent(optionContainer); btn.setIcon(btnIcons[direction]); btn.setClass("small"); btn.setDisabled( index === 0 && direction === "asc" || index === this.orderedOptions.length && direction === "desc" ); btn.onClick(() => { if (direction === "asc") { swapElements(this.orderedOptions, index - 1, index); } else { swapElements(this.orderedOptions, index, index + 1); } this.buildOrderedOptions(); }); return btn; }; buildPrioBtn("asc"); buildPrioBtn("desc"); const labelContainer = optionContainer.createDiv({ cls: "label" }); labelContainer.setText(option); } buildOrderedOptions() { this.optionsContainer.replaceChildren(); this.orderedOptions.forEach((option, index) => this.renderOption(option, index)); } updateCustomOrder(newOrder) { this.rowSorterComponent.customOrder = newOrder; this.rowSorterComponent.toggleRowSorterButtonsState("asc"); this.parentFieldSet.tableView.update(); this.parentFieldSet.tableView.saveViewBtn.setCta(); } buildConfirm(footerActionsContainer) { const infoContainer = footerActionsContainer.createDiv({ cls: "info" }); infoContainer.setText("Alt+Enter to save"); this.confirmButton = new import_obsidian45.ButtonComponent(footerActionsContainer); this.confirmButton.setIcon("checkmark"); this.confirmButton.onClick(() => { this.updateCustomOrder(this.orderedOptions); this.close(); }); } buildFooterActions(footerActionsContainer) { footerActionsContainer.createDiv({ cls: "spacer" }); this.buildConfirm(footerActionsContainer); const cancelButton = new import_obsidian45.ButtonComponent(footerActionsContainer); cancelButton.setIcon("cross"); cancelButton.onClick(() => this.close()); cancelButton.setTooltip("Cancel"); const refreshButton = new import_obsidian45.ButtonComponent(footerActionsContainer); refreshButton.setIcon("refresh-ccw"); refreshButton.setTooltip("Cancel changes"); refreshButton.onClick(async () => { this.orderedOptions = this.rowSorterComponent.customOrder || this.getOptions(); this.buildOrderedOptions(); this.confirmButton.removeCta(); }); const resetButton = new import_obsidian45.ButtonComponent(footerActionsContainer); resetButton.setIcon("eraser"); resetButton.setTooltip("Reset initial ordering"); resetButton.onClick(async () => { this.orderedOptions = this.getOptions(); this.rowSorterComponent.toggleRowSorterButtonsState(void 0); this.buildOrderedOptions(); this.confirmButton.setCta(); }); this.modalEl.appendChild(footerActionsContainer); } }; // src/fileClass/views/tableViewComponents/RowSorterComponent.ts var RowSorterComponent = class { constructor(parentFieldset, fileClass, fieldContainer, name, direction, priority, customOrder) { this.parentFieldset = parentFieldset; this.fileClass = fileClass; this.fieldContainer = fieldContainer; this.name = name; this.direction = direction; this.priority = priority; this.customOrder = customOrder; this.buildSorterBtn = (direction) => { const btn = new import_obsidian46.ButtonComponent(this.fieldContainer); btn.setIcon(btnIcons[direction]); btn.onClick(() => { this.toggleRowSorterButtonsState(direction); this.parentFieldset.tableView.update(); this.parentFieldset.tableView.saveViewBtn.setCta(); }); return btn; }; this.id = `${this.fileClass.name}____${this.name}`; this.ascBtn = this.buildSorterBtn("asc"); this.descBtn = this.buildSorterBtn("desc"); this.customOrderBtn = new import_obsidian46.ButtonComponent(fieldContainer); this.customOrderBtn.setIcon("list-ordered"); this.customOrderBtn.onClick(() => { var _a; const plugin = this.parentFieldset.plugin; const fileClass2 = this.parentFieldset.fileClass; const fileClassFile = fileClass2.getClassFile(); const field2 = (_a = plugin.fieldIndex.fileClassesFields.get(fileClass2.name)) == null ? void 0 : _a.find((f) => f.isRoot() && f.name === this.name); new OptionsPriorityModal(plugin, fileClassFile, field2 || "file", this.parentFieldset, this).open(); }); } toggleRowSorterButtonsState(direction) { var _a; this.direction = this.direction === direction ? void 0 : direction; switch (this.direction) { case void 0: this.ascBtn.buttonEl.removeClass("active"); this.descBtn.buttonEl.removeClass("active"); break; case "asc": this.ascBtn.buttonEl.addClass("active"); this.descBtn.buttonEl.removeClass("active"); break; case "desc": this.ascBtn.buttonEl.removeClass("active"); this.descBtn.buttonEl.addClass("active"); break; } if (!this.direction) { this.changeRowSorterPriority(void 0); } else { if (!this.priority) { const newPriority = this.getMaxRowSorterPriority() + 1; this.changeRowSorterPriority(newPriority); } } if (!((_a = this.customOrder) == null ? void 0 : _a.length)) { this.customOrderBtn.buttonEl.removeClass("active"); } else { this.customOrderBtn.buttonEl.addClass("active"); } } changeRowSorterPriority(priority) { const currentPriority = this.priority; Object.keys(this.parentFieldset.rowSorters).forEach((_id) => { const field2 = this.parentFieldset.fieldComponents.find((f) => f.id === _id); const sorter = this.parentFieldset.rowSorters[_id]; if (_id == this.id) { sorter.priority = !currentPriority ? priority : void 0; field2.priorityLabelContainer.textContent = sorter.priority ? `(${sorter.priority})` : ""; } else if (currentPriority && sorter.priority && !priority && sorter.priority > currentPriority) { sorter.priority = sorter.priority - 1; field2.priorityLabelContainer.textContent = `(${sorter.priority})`; } }); } getMaxRowSorterPriority() { const maxPrio = Object.values(this.parentFieldset.rowSorters).reduce((intermediateMax, currentSorter) => Math.max(intermediateMax, currentSorter.priority || 0), 0); return maxPrio; } }; // src/fileClass/views/tableViewComponents/FilterComponent.ts var import_obsidian49 = require("obsidian"); // src/fileClass/views/tableViewComponents/OptionsMultiSelectModal.ts var import_obsidian47 = require("obsidian"); var fieldStates = /* @__PURE__ */ ((fieldStates2) => { fieldStates2["__empty__"] = "__empty__"; fieldStates2["__notEmpty__"] = "__notEmpty__"; fieldStates2["__notFound__"] = "__notFound__"; fieldStates2["__existing__"] = "__existing__"; return fieldStates2; })(fieldStates || {}); var displayValue26 = { __empty__: "Empty Fields", __notEmpty__: "Not Empty Fields", __notFound__: "Not Found Fields", __existing__: "Existing Fields" }; var displayIcon = { __empty__: "box-select", __notEmpty__: "plus-square", __notFound__: "x-circle", __existing__: "circle-dot" }; var OptionsMultiSelectModal = class extends import_obsidian47.SuggestModal { constructor(plugin, fileClassFile, field2, parentFieldSet) { super(plugin.app); this.plugin = plugin; this.fileClassFile = fileClassFile; this.field = field2; this.parentFieldSet = parentFieldSet; this.containerEl.addClass("metadata-menu"); const inputContainer = this.containerEl.createDiv({ cls: "suggester-input" }); inputContainer.appendChild(this.inputEl); this.containerEl.find(".prompt").prepend(inputContainer); cleanActions(this.containerEl, ".footer-actions"); const footerActionsContainer = this.containerEl.createDiv({ cls: "footer-actions" }); this.buildFooterActions(footerActionsContainer); const id = this.field === "file" ? "file" : `${this.fileClassFile.basename.replace(/.md$/, "")}____${this.field.name}`; this.input = this.parentFieldSet.filters[id].filter; const initialOptions = this.input.getValue(); if (initialOptions) { if (Array.isArray(initialOptions)) { this.selectedOptions = initialOptions.map((item) => { const link = getLink(item, fileClassFile); if (link) { return buildMarkDownLink(this.plugin, fileClassFile, link.path); } else { return item.toString(); } }); this.selectedOptions = initialOptions.map((item) => item.toString()); } else if (typeof initialOptions === "string" && initialOptions.toString().startsWith("[[")) { this.selectedOptions = initialOptions.split(",").map((item) => item.trim()); } else { const link = getLink(initialOptions, fileClassFile); if (link) { this.selectedOptions = [`[[${link.path.replace(".md", "")}]]`]; } else if (typeof initialOptions === "string") { this.selectedOptions = initialOptions.toString().replace(/^\[(.*)\]$/, "$1").split(",").map((item) => item.trim()); } } } else { this.selectedOptions = []; } this.containerEl.onkeydown = async (e) => { if (e.key == "Enter" && e.altKey) { await this.replaceOptionsValues(); this.close(); } }; } getSuggestions(query) { if (this.field === "file") { return []; } else { const commonStates = Object.keys(fieldStates); const field2 = this.field; switch (field2.type) { case "Boolean": { return [...commonStates, "true", "false"]; } case "Multi": case "Select": { const field3 = getField(this.field.id, this.field.fileClassName, this.plugin); const values = field3 ? getOptionsList(field3).filter((o) => String(o).toLowerCase().includes(query.toLowerCase())) : []; return [...commonStates, ...values]; } case "MultiFile": case "File": { const sortingMethod = new Function("a", "b", `return ${field2.options.customSorting}`) || function(a, b) { return a.basename < b.basename ? -1 : 1; }; try { const field3 = getField(this.field.id, this.field.fileClassName, this.plugin); const values = (field3 ? getFiles(field3) : []).sort(sortingMethod).map((item) => item.basename.trim().replace(/\[\[|\]\]/g, "")).filter((o) => String(o).toLowerCase().includes(query.toLowerCase())); return ["__empty__", "__notEmpty__", ...values]; } catch (error) { return []; } } case "Lookup": { const _values = [...this.plugin.fieldIndex.fileLookupFieldLastValue.entries()].filter(([fieldId, lookupFiles]) => { return fieldId.endsWith(`__related__${this.fileClassFile.basename}___${this.field.name}`) && lookupFiles !== ""; }).map(([fieldId, lookupFiles]) => lookupFiles).join(","); const values = [...new Set( _values.split(",").map((item) => item.trim().replace(/\[\[|\]\]/g, "")).filter((o) => String(o).toLowerCase().includes(query.toLowerCase())) )]; return [...commonStates, ...values]; } default: return [...commonStates]; } } } buildFooterActions(footerActionsContainer) { footerActionsContainer.createDiv({ cls: "spacer" }); this.buildConfirm(footerActionsContainer); const cancelButton = new import_obsidian47.ButtonComponent(footerActionsContainer); cancelButton.setIcon("cross"); cancelButton.onClick(() => this.close()); cancelButton.setTooltip("Cancel"); const clearButton = new import_obsidian47.ButtonComponent(footerActionsContainer); clearButton.setIcon("filter-x"); clearButton.setTooltip("Clear filtered value(s)"); clearButton.onClick(async () => { this.input.setValue(""); this.parentFieldSet.tableView.update(); this.parentFieldSet.tableView.saveViewBtn.setCta(); this.close(); }); clearButton.buttonEl.addClass("danger"); this.modalEl.appendChild(footerActionsContainer); } buildConfirm(footerActionsContainer) { const infoContainer = footerActionsContainer.createDiv({ cls: "info" }); infoContainer.setText("Alt+Enter to save"); const confirmButton = new import_obsidian47.ButtonComponent(footerActionsContainer); confirmButton.setIcon("checkmark"); confirmButton.onClick(async () => { await this.replaceOptionsValues(); this.close(); }); } async replaceOptionsValues() { const options2 = this.selectedOptions; this.input.inputEl.value = options2.join(", "); this.parentFieldSet.tableView.update(); this.parentFieldSet.tableView.saveViewBtn.setCta(); this.close(); } renderSelected() { const chooser = this.chooser; const suggestions = chooser.suggestions; const values = chooser.values; suggestions.forEach((s, i) => { if (this.selectedOptions.includes(values[i].toString())) { s.addClass("value-checked"); if (s.querySelectorAll(".icon-container").length == 0) { const iconContainer = s.createDiv({ cls: "icon-container" }); (0, import_obsidian47.setIcon)(iconContainer, "check-circle"); } } else { s.removeClass("value-checked"); s.querySelectorAll(".icon-container").forEach((icon) => icon.remove()); } }); } renderSuggestion(value, el) { const labelContainer = el.createDiv({ cls: "label-with-icon-container" }); const icon = labelContainer.createDiv({ cls: "icon" }); if (Object.keys(fieldStates).includes(value)) { (0, import_obsidian47.setIcon)(icon, displayIcon[value]); } const label = labelContainer.createDiv({ cls: "label" }); let labelText = ""; if (Object.keys(fieldStates).includes(value)) { labelText = displayValue26[value]; } else { labelText = `${value.slice(0, 50)}${value.length > 50 ? "..." : ""}`; } label.setText(labelText); el.addClass("value-container"); const spacer = this.containerEl.createDiv({ cls: "spacer" }); el.appendChild(spacer); if (this.selectedOptions.includes(value.toString())) { el.addClass("value-checked"); const iconContainer = el.createDiv({ cls: "icon-container" }); (0, import_obsidian47.setIcon)(iconContainer, "check-circle"); } this.inputEl.focus(); } selectSuggestion(value, evt) { if (this.selectedOptions.includes(value.toString())) { this.selectedOptions.remove(value.toString()); } else { if (Object.keys(fieldStates).includes(value)) { this.selectedOptions = [value]; } else { this.selectedOptions = [...this.selectedOptions.filter((o) => !Object.keys(fieldStates).includes(o))]; this.selectedOptions.push(value.toString()); } } this.renderSelected(); } onChooseSuggestion(item, evt) { } }; // src/fileClass/views/tableViewComponents/CustomFilterModal.ts var import_obsidian48 = require("obsidian"); var CustomFilterModal = class extends import_obsidian48.Modal { constructor(plugin, parentFieldSet, filterComponent) { super(plugin.app); this.plugin = plugin; this.parentFieldSet = parentFieldSet; this.filterComponent = filterComponent; this.containerEl.addClass("metadata-menu"); this.titleEl.setText("Enter a custom filtering function"); this.buildInput(); cleanActions(this.containerEl, ".footer-actions"); const footerActionsContainer = this.containerEl.createDiv({ cls: "footer-actions" }); this.buildFooterActions(footerActionsContainer); } buildInput() { this.contentEl.createDiv({ cls: "info-code" }).createEl("code", { text: `(value: string, current: Object): boolean => {` }); this.contentEl.createDiv({ cls: "info-code" }).createEl("code", { text: `/*` }); this.contentEl.createDiv({ cls: "info-code" }).createEl("code", { text: `value is the value of the file's ${this.filterComponent.name} field` }); this.contentEl.createDiv({ cls: "info-code" }).createEl("code", { text: `current is the current page (dv.page) if this view is embedded in a codeblock` }); this.contentEl.createDiv({ cls: "info-code" }).createEl("code", { text: `returns a boolean, ` }); this.contentEl.createDiv({ cls: "info-code" }).createEl("code", { text: `double quote have to be escaped like this \\", ` }); this.contentEl.createDiv({ cls: "info-code" }).createEl("code", { text: `example:` }); this.contentEl.createDiv({ cls: "info-code" }).createEl("code", { text: `return value < current.priority;` }); this.contentEl.createDiv({ cls: "info-code" }).createEl("code", { text: `*/` }); const subContent = this.contentEl.createDiv({ cls: "field-container" }); this.filterFunctionInput = new import_obsidian48.TextAreaComponent(subContent).setValue(this.filterComponent.customFilter || "").onChange(() => { this.confirmButton.setCta(); }); this.filterFunctionInput.inputEl.rows = 6; this.filterFunctionInput.inputEl.addClass("full-width"); this.contentEl.createDiv({ cls: "info-code" }).createEl("code", { text: "};" }); } updateCustomFilter() { this.filterComponent.customFilter = this.filterFunctionInput.getValue(); this.filterComponent.toggleCustomFilterState(); this.parentFieldSet.tableView.update(); this.parentFieldSet.tableView.saveViewBtn.setCta(); } buildConfirm(footerActionsContainer) { const infoContainer = footerActionsContainer.createDiv({ cls: "info" }); infoContainer.setText("Alt+Enter to save"); this.confirmButton = new import_obsidian48.ButtonComponent(footerActionsContainer); this.confirmButton.setIcon("checkmark"); this.confirmButton.onClick(() => { if (true) this.updateCustomFilter(); this.close(); }); } buildFooterActions(footerActionsContainer) { footerActionsContainer.createDiv({ cls: "spacer" }); this.buildConfirm(footerActionsContainer); const cancelButton = new import_obsidian48.ButtonComponent(footerActionsContainer); cancelButton.setIcon("cross"); cancelButton.onClick(() => this.close()); cancelButton.setTooltip("Cancel"); const refreshButton = new import_obsidian48.ButtonComponent(footerActionsContainer); refreshButton.setIcon("refresh-ccw"); refreshButton.setTooltip("Cancel changes"); refreshButton.onClick(async () => { this.filterFunctionInput.setValue(this.filterComponent.customFilter); this.confirmButton.removeCta(); }); const resetButton = new import_obsidian48.ButtonComponent(footerActionsContainer); resetButton.setIcon("eraser"); resetButton.setTooltip("Reset initial ordering"); resetButton.onClick(async () => { this.filterFunctionInput.setValue(""); this.filterComponent.toggleCustomFilterState(); this.confirmButton.setCta(); }); this.modalEl.appendChild(footerActionsContainer); } }; // src/fileClass/views/tableViewComponents/FilterComponent.ts var FilterComponent = class { constructor(fileClass, container, name, parentFieldSet, debounced) { this.fileClass = fileClass; this.container = container; this.name = name; this.parentFieldSet = parentFieldSet; this.debounced = debounced; this.id = `${fileClass.name}____${this.name}`; this.build(); } build() { this.filter = new import_obsidian49.TextComponent(this.container); this.container.addClass("filter-with-dropdown"); this.filter.setValue(""); this.filter.onChange((value) => { this.filter.inputEl.value = value; this.debounced(this.parentFieldSet); }); if (this.name !== "file") { this.buildDropdownBtn(); } this.buildCustomFilterBtn(); } buildDropdownBtn() { var _a; const button = this.container.createEl("button", { cls: "infield-button" }); (_a = this.filter.inputEl.parentElement) == null ? void 0 : _a.appendChild(button); (0, import_obsidian49.setIcon)(button, "chevron-down"); button.onclick = () => { var _a2; const plugin = this.parentFieldSet.plugin; const fileClassFile = this.fileClass.getClassFile(); const field2 = (_a2 = plugin.fieldIndex.fileClassesFields.get(this.fileClass.name)) == null ? void 0 : _a2.find((f) => f.isRoot() && f.name === this.name); new OptionsMultiSelectModal(plugin, fileClassFile, field2 || "file", this.parentFieldSet).open(); }; } toggleCustomFilterState() { if (this.customFilter) this.filterBtn.buttonEl.addClass("active"); else this.filterBtn.buttonEl.removeClass("active"); } buildCustomFilterBtn() { var _a; this.filterBtn = new import_obsidian49.ButtonComponent(this.container); this.filterBtn.buttonEl.addClass("infield-button"); (_a = this.filter.inputEl.parentElement) == null ? void 0 : _a.appendChild(this.filterBtn.buttonEl); this.filterBtn.setIcon("code-2"); this.filterBtn.onClick(() => { const plugin = this.parentFieldSet.plugin; new CustomFilterModal(plugin, this.parentFieldSet, this).open(); }); } }; // src/fileClass/views/tableViewComponents/FieldComponent.ts var FieldComponent = class { constructor(fileClass, container, parentFieldSet, name, label, columnPosition, rowPriority, isColumnHidden = false, rowSortingDirection = void 0, query = "", customOrder = []) { this.fileClass = fileClass; this.container = container; this.parentFieldSet = parentFieldSet; this.name = name; this.label = label; this.columnPosition = columnPosition; this.rowPriority = rowPriority; this.isColumnHidden = isColumnHidden; this.rowSortingDirection = rowSortingDirection; this.query = query; this.customOrder = customOrder; this.id = `${this.fileClass.name}____${this.name}`; this.buildFieldHeaderComponent(); this.buildFieldComponent(); } canMove(direction) { return !(this.columnPosition === 0 && direction === "left" || this.columnPosition === this.parentFieldSet.fieldComponents.length - 1 && direction === "right"); } buildColumnMoverBtn(component) { const buildBtn = (direction) => { const btn = new import_obsidian50.ButtonComponent(component); btn.setIcon(btnIcons[direction]); btn.onClick(() => { if (this.canMove(direction)) { this.parentFieldSet.moveColumn(this.id, direction); this.parentFieldSet.reorderFields(); this.parentFieldSet.tableView.update(); this.parentFieldSet.tableView.saveViewBtn.setCta(); } }); return btn; }; const leftBtn = buildBtn("left"); const rightBtn = buildBtn("right"); this.parentFieldSet.columnManagers[this.id] = { id: this.id, name: this.name, hidden: false, leftBtn, rightBtn, position: this.columnPosition }; } buildRowSorterComponent(fileClass, fieldHeader) { const rowSorterComponent = new RowSorterComponent( this.parentFieldSet, fileClass, fieldHeader, this.name, this.rowSortingDirection, this.rowPriority, this.customOrder ); this.parentFieldSet.rowSorters[this.id] = rowSorterComponent; } setVisibilityButtonState(isHidden) { this.isColumnHidden = isHidden; this.parentFieldSet.columnManagers[this.id].hidden = this.isColumnHidden; this.visibilityButton.setIcon(this.isColumnHidden ? "eye-off" : "eye"); } buildVisibilityBtn(component) { this.visibilityButton = new import_obsidian50.ButtonComponent(component).setIcon(this.isColumnHidden ? "eye-off" : "eye").onClick(() => { this.setVisibilityButtonState(!this.isColumnHidden); this.parentFieldSet.tableView.update(); this.parentFieldSet.tableView.saveViewBtn.setCta(); }); } buildFieldHeaderComponent() { var _a; if (this.parentFieldSet.children.length) { this.container.createDiv({ text: this.fileClass.name, cls: "field-fileclass-header" }); } const container = this.container.createDiv({ cls: "field-header" }); this.buildRowSorterComponent(this.fileClass, container); const prioAndLabelContainer = container.createDiv({ cls: "label-container" }); prioAndLabelContainer.createDiv({ text: this.label, cls: "field-name" }); const priorityLabel = ((_a = this.parentFieldSet.rowSorters[this.id]) == null ? void 0 : _a.priority) ? `(${this.parentFieldSet.rowSorters[this.id].priority})` : ""; this.priorityLabelContainer = prioAndLabelContainer.createDiv({ cls: "priority", text: priorityLabel }); this.buildVisibilityBtn(container); this.buildColumnMoverBtn(container); } buildFilter(name, debounced) { const fieldFilterContainer = this.container.createDiv({ cls: "filter-input" }); const filterComponent = new FilterComponent(this.fileClass, fieldFilterContainer, name, this.parentFieldSet, debounced); this.parentFieldSet.filters[filterComponent.id] = filterComponent; } buildFieldComponent() { var _a; const field2 = (_a = this.parentFieldSet.plugin.fieldIndex.fileClassesFields.get(this.parentFieldSet.fileClass.name)) == null ? void 0 : _a.find((f) => f.name === this.name); const debounced = (0, import_obsidian50.debounce)((fieldset) => { fieldset.tableView.update(); this.parentFieldSet.tableView.saveViewBtn.setCta(); }, 1e3, true); this.buildFilter((field2 == null ? void 0 : field2.name) || "file", debounced); } }; // src/fileClass/views/tableViewComponents/tableViewFieldSet.ts var btnIcons = { "asc": "chevron-up", "desc": "chevron-down", "left": "chevron-left", "right": "chevron-right" }; var FieldSet4 = class { constructor(tableView, container) { this.tableView = tableView; this.container = container; this.fieldComponents = []; this.filters = {}; this.rowSorters = {}; this.columnManagers = {}; this.plugin = tableView.plugin; this.build(); } build(children) { this.fileClass = this.plugin.fieldIndex.fileClassesName.get(this.tableView.fileClass.name); this.children = children || this.fileClass.getViewChildren(this.tableView.manager.selectedView); this.fileClasses = [this.fileClass, ...this.children.map((c) => c.fileClass)]; this.container.replaceChildren(); this.buildFieldComponents(); } buildFieldComponents() { this.fieldComponents = []; const fileFieldContainer = this.container.createDiv({ cls: "field-container" }); const fieldComponent = new FieldComponent(this.fileClass, fileFieldContainer, this, "file", "File Name", 0); this.fieldComponents.push(fieldComponent); let index = 0; this.fileClasses.forEach((_fC) => { const sortedFields = getSortedRootFields(this.plugin, _fC); for (const [_index, field2] of sortedFields.entries()) { const fieldContainer = this.container.createDiv({ cls: "field-container" }); this.fieldComponents.push(new FieldComponent(_fC, fieldContainer, this, field2.name, field2.name, _index + index + 1)); } index += sortedFields.length; }); } reorderFields() { this.fieldComponents.sort((f1, f2) => f1.columnPosition - f2.columnPosition).forEach((field2) => this.container.appendChild(field2.container)); } moveColumn(id, direction) { const currentPosition = this.columnManagers[id].position; Object.keys(this.columnManagers).forEach((_id) => { const mover = this.columnManagers[_id]; const field2 = this.fieldComponents.find((f) => f.id === _id); switch (direction) { case "left": if (mover.position === currentPosition - 1) { mover.position++; field2.columnPosition++; break; } if (mover.position === currentPosition) { mover.position--; field2.columnPosition--; break; } break; case "right": if (mover.position === currentPosition + 1) { mover.position--; field2.columnPosition--; break; } if (mover.position === currentPosition) { mover.position++; field2.columnPosition++; break; } break; } }); } reset(children, updateNeeded = true) { this.rowSorters = {}; this.filters = {}; this.columnManagers = {}; this.build(children); if (updateNeeded) this.tableView.update(); this.tableView.saveViewBtn.setCta(); } getParams() { const children = this.children; const filters = Object.entries(this.filters).map(([id, filterComponent]) => { return { id, name: filterComponent.name, query: filterComponent.filter.getValue(), customFilter: filterComponent.customFilter }; }); const sorters = Object.entries(this.rowSorters).filter(([id, s]) => { var _a; return s.direction !== void 0 || ((_a = s.customOrder) == null ? void 0 : _a.length); }).map(([id, sorter]) => { return { id, name: sorter.name, direction: sorter.direction || "asc", priority: sorter.priority || 0, customOrder: sorter.customOrder || [] }; }); const columns = Object.entries(this.columnManagers).map(([id, columnManager]) => { return { id, name: columnManager.name, hidden: columnManager.hidden, position: columnManager.position }; }); return { children: children.map((c) => c.name), filters, sorters, columns }; } resetColumnManagers() { Object.keys(this.columnManagers).forEach((id) => { const fCFields = []; this.fileClasses.forEach((fC) => { var _a, _b; (_b = (_a = this.plugin.fieldIndex.fileClassesFields.get(this.fileClass.name)) == null ? void 0 : _a.filter((_f) => _f.isRoot())) == null ? void 0 : _b.forEach((_f) => { fCFields.push(_f); }); }); for (const [_index, _field] of fCFields.entries()) { const field2 = this.fieldComponents.find((f) => f.name === _field.name && f.fileClass.name === _field.fileClassName); if (field2 && field2.id === id) { field2.columnPosition = _index + 1; field2.setVisibilityButtonState(false); this.columnManagers[id].position = _index + 1; } } if (id === "file") { const field2 = this.fieldComponents.find((f) => f.name === "file"); if (field2) { field2.columnPosition = 0; field2.setVisibilityButtonState(false); this.columnManagers[id].position = 0; } } }); } changeView(_name, updateNeeded = true) { const options2 = this.fileClass.getFileClassOptions(); const savedViews = options2.savedViews || []; this.tableView.manager.selectedView = _name || ""; this.reset(void 0, updateNeeded); if (_name && savedViews.find((view) => view.name === _name)) { const savedView = savedViews.find((view) => view.name === _name); Object.keys(this.filters).forEach((id) => { const filterComponent = this.filters[id]; const savedFilter = savedView == null ? void 0 : savedView.filters.find((f) => f.id === id || !f.id && f.name === filterComponent.name); filterComponent.filter.inputEl.value = (savedFilter == null ? void 0 : savedFilter.query) || ""; filterComponent.customFilter = (savedFilter == null ? void 0 : savedFilter.customFilter) || ""; filterComponent.toggleCustomFilterState(); }); Object.keys(this.rowSorters).forEach((id) => { var _a; const rowSorter = this.rowSorters[id]; const savedSorter = (_a = savedView == null ? void 0 : savedView.sorters) == null ? void 0 : _a.find((f) => f.id === id || !f.id && f.name === rowSorter.name); if (savedSorter) { rowSorter.priority = savedSorter.priority; rowSorter.customOrder = savedSorter.customOrder; rowSorter.toggleRowSorterButtonsState(savedSorter.direction); const field2 = this.fieldComponents.find((f) => f.id === id); field2.priorityLabelContainer.textContent = `(${savedSorter.priority})`; } else { rowSorter.direction = void 0; rowSorter.ascBtn.buttonEl.removeClass("active"); rowSorter.descBtn.buttonEl.removeClass("active"); } }); Object.keys(this.columnManagers).forEach((id) => { const mover = this.columnManagers[id]; const field2 = this.fieldComponents.find((f) => f.id === id || !f.id && f.name === mover.name); for (const column of savedView.columns || []) { if (column.id === id) { mover.position = column.position; field2.columnPosition = column.position; field2.setVisibilityButtonState(column.hidden); } } }); } this.reorderFields(); } }; // src/fileClass/views/tableViewComponents/saveViewModal.ts var import_obsidian51 = require("obsidian"); var SavedView = class { constructor(name) { this.name = name; this.children = []; this.sorters = []; this.filters = []; this.columns = []; } buildFilters(filters) { Object.entries(filters).forEach(([id, filterComponent]) => { this.filters.push({ id, name: filterComponent.name, query: filterComponent.filter.inputEl.value, customFilter: filterComponent.customFilter }); }); } buildRowSorters(rowSorters) { Object.keys(rowSorters).forEach((id) => { var _a; const sorter = rowSorters[id]; if (sorter.direction || ((_a = sorter.customOrder) == null ? void 0 : _a.length)) { this.sorters.push({ id, name: sorter.name, direction: sorter.direction || "asc", priority: sorter.priority || 0, customOrder: sorter.customOrder || [] }); } }); } buildColumnManagers(columnManagers) { Object.entries(columnManagers).forEach(([id, column]) => { this.columns.push({ id, name: column.name, hidden: column.hidden, position: column.position }); }); } }; var CreateSavedViewModal = class extends import_obsidian51.Modal { constructor(plugin, view) { super(plugin.app); this.view = view; this.containerEl.onkeydown = (e) => { if (e.key == "Enter" && e.altKey) { e.preventDefault(); this.save(); } if (e.key === "Escape" && e.altKey) { this.close(); } }; this.savedView = new SavedView(""); this.savedView.children = view.fieldSet.children.map((c) => c.name); this.savedView.buildFilters(view.fieldSet.filters); this.savedView.buildRowSorters(view.fieldSet.rowSorters); this.savedView.buildColumnManagers(view.fieldSet.columnManagers); this.buildModal(); this.containerEl.addClass("metadata-menu"); } buildModal() { const nameContainer = this.contentEl.createDiv({ cls: "field-container" }); nameContainer.createDiv({ text: `Saved view name`, cls: "label" }); const nameInput = new import_obsidian51.TextComponent(nameContainer); nameInput.inputEl.addClass("with-label"); nameInput.inputEl.addClass("full-width"); const nameErrorContainer = this.contentEl.createDiv({ cls: "field-error", text: `This ${this.savedView.name} view name already exists` }); cleanActions(this.contentEl, ".footer-actions"); const actionsContainer = this.contentEl.createDiv({ cls: "footer-actions" }); actionsContainer.createDiv({ cls: "spacer" }); const infoContainer = actionsContainer.createDiv({ cls: "info" }); infoContainer.setText("Alt+Enter to save"); const saveBtn = new import_obsidian51.ButtonComponent(actionsContainer); saveBtn.setDisabled(true); saveBtn.setIcon("file-plus-2"); nameErrorContainer.hide(); nameInput.onChange(async (value) => { this.savedView.name = value; nameErrorContainer.hide(); saveBtn.setDisabled(false); saveBtn.setCta(); }); saveBtn.onClick(async () => { await this.save(); }); if (this.view.selectedView) { nameInput.setValue(this.view.selectedView); this.savedView.name = this.view.selectedView; saveBtn.setDisabled(false); saveBtn.setCta(); } } async save() { var _a; const options2 = this.view.fileClass.getFileClassOptions(); options2.savedViews = [...((_a = options2.savedViews) == null ? void 0 : _a.filter((v) => v.name !== this.savedView.name)) || [], this.savedView]; await this.view.fileClass.updateOptions(options2); this.view.selectedView = this.savedView.name; this.view.favoriteBtn.buttonEl.disabled = false; this.view.update(); this.view.saveViewBtn.removeCta(); this.close(); } }; // src/fileClass/views/tableViewComponents/fileClassDataviewTable.ts var import_obsidian52 = require("obsidian"); var FileClassDataviewTable = class { constructor(viewConfiguration, view, fileClass, maxRow, sliceStart = 0, ctx) { this.viewConfiguration = viewConfiguration; this.view = view; this.fileClass = fileClass; this.sliceStart = sliceStart; this.ctx = ctx; this.ranges = []; this.limitWrapped = false; this.columnsFileClassField = {}; this.observers = []; this.plugin = this.view.manager.plugin; this.limit = maxRow || this.fileClass.options.limit || this.plugin.settings.tableViewMaxRecords; } getFilteredFiles() { var _a; const dvApi = (_a = this.plugin.app.plugins.plugins.dataview) == null ? void 0 : _a.api; if (dvApi) { try { const current = this.ctx ? dvApi.page(this.ctx.sourcePath) : {}; const fFC = this.plugin.fieldIndex.filesFileClasses; const fileClassesNames = [this.fileClass.name, ...this.viewConfiguration.children]; const fileClassFiles = [...fFC.keys()].filter((path) => { var _a2; return (_a2 = fFC.get(path)) == null ? void 0 : _a2.some((_fileClass) => fileClassesNames.includes(_fileClass.name)); }); const fileFileClasses = (path) => { var _a2; return ((_a2 = this.plugin.fieldIndex.filesFileClasses.get(path)) == null ? void 0 : _a2.map((_fC) => _fC.name)) || []; }; const hasFileClass = (path, id) => { if (id.includes("____")) { const fileClassName = id.split("____")[0]; return fileFileClasses(path).includes(fileClassName); } else { return true; } }; const query = new Function( "dv", "current", "fileClassFiles", "hasFileClass", `return ${this.buildDvJSQuery()}` )(dvApi, current, fileClassFiles, hasFileClass); const values = query.values; return values; } catch (e) { console.log(e); console.error("unable to build the list of files"); } } else { return []; } } buildPaginationManager(container) { container.replaceChildren(); this.ranges = []; const toggleRanges = (rangesCount2) => { for (const [index, rangeComponent] of this.ranges.entries()) { if (rangesCount2 >= 5 && index > 2 && index < rangesCount2 - 2) { if (this.limitWrapped) rangeComponent.show(); else rangeComponent.hide(); } } this.limitWrapped = !this.limitWrapped; }; const values = this.getFilteredFiles() || []; this.count = values.length; const rangesCount = Math.floor(this.count / this.limit) + 1; if (rangesCount < 2) return; for (let i = 0; i < rangesCount; i++) { if (i * this.limit < this.count) { const rangeComponent = container.createDiv({ cls: `range ${i === this.sliceStart / this.limit ? "active" : ""}`, text: `${i * this.limit + 1} - ${Math.min((i + 1) * this.limit, this.count)}` }); rangeComponent.onclick = () => { this.sliceStart = i * this.limit; this.view.update(this.limit, this.sliceStart); }; this.ranges.push(rangeComponent); } if (rangesCount >= 5 && i === 2) { const rangeExpander = container.createDiv({ cls: `range`, text: `< ... >` }); rangeExpander.onclick = () => { if (rangeExpander.hasClass("active")) { rangeExpander.removeClass("active"); rangeExpander.setText("< ... >"); } else { rangeExpander.addClass("active"); rangeExpander.setText("> ... <"); } toggleRanges(rangesCount); }; } } const activeRange = this.ranges.find((r) => r.hasClass("active")); if (activeRange && this.ranges.indexOf(activeRange) < 2) toggleRanges(rangesCount); } addLinkClickEvent(observed) { var callback = function(mutationsList, table) { for (var mutation of mutationsList) { if (mutation.type == "childList") { for (const node of mutation.addedNodes) { if ("className" in node && typeof node.className === "string" && node.className.includes("field-name")) { const fileLink = node.querySelector("span a.internal-link"); if (fileLink) table.addClickEventToLink(fileLink); } } } } }; const observer = new MutationObserver((mutationList) => callback(mutationList, this)); if (observed) observer.observe(observed, { childList: true }); } buildBulkModifiers(observed) { const cleanTable = (table) => { var _a, _b; for (const selector of table.querySelectorAll(".modifier-selector")) { (_a = selector.parentElement) == null ? void 0 : _a.removeChild(selector); } for (const toggler of table.querySelectorAll(".checkbox-toggler")) { (_b = toggler.parentElement) == null ? void 0 : _b.removeChild(toggler); } }; const processFilesFieldChange = (dvTable, selectedFiles, allFilesSelected, columndId) => { var _a; const { fileClassName, fieldName } = dvTable.columnsFileClassField[columndId]; const field2 = (_a = this.plugin.fieldIndex.fileClassesFields.get(fileClassName)) == null ? void 0 : _a.find((f) => f.isRoot() && f.name === fieldName); const files = selectedFiles.map((sF) => this.plugin.app.vault.getAbstractFileByPath(sF)).filter((f) => f instanceof import_obsidian52.TFile); if (field2) { const fieldVM = fieldValueManager(this.plugin, field2.id, field2.fileClassName, files, void 0); fieldVM == null ? void 0 : fieldVM.openModal(); } }; const buildCellCheckBox = (table, cell, filesCheckboxes, allFilesSelected, selectedFiles) => { const checkBoxContainer = cell.createDiv({ cls: "modifier-selector" }); const checkBox = checkBoxContainer.createEl("input", { type: "checkbox" }); if (cell.tagName === "TH") checkBox.addClass("page-checkbox"); else filesCheckboxes.push(checkBox); checkBox.onclick = (e) => { var _a; e.stopPropagation(); checkBox.toggleAttribute("checked"); if (cell.tagName === "TH") { allFilesSelected = checkBox.checked; for (const cB of filesCheckboxes) cB.checked = false; selectedFiles.splice(0); if (allFilesSelected) { for (const cell2 of table.querySelectorAll("div.field-name a.internal-link")) { const name = cell2 == null ? void 0 : cell2.getAttr("data-href"); if (name) selectedFiles.push(name); } for (const cB of filesCheckboxes) cB.checked = true; } } else { const headerCheckbox = table.querySelector(".page-checkbox"); if (headerCheckbox) { headerCheckbox.checked = false; allFilesSelected = false; } const name = (_a = cell.querySelector("div.field-name a.internal-link")) == null ? void 0 : _a.getAttr("data-href"); if (checkBox.checked && name) selectedFiles.push(name); else if (name) selectedFiles.remove(name); } }; checkBoxContainer.hide(); cell.prepend(checkBoxContainer); }; const buildHeaderCols = (dvTable, table, selectedFiles, allFilesSelected) => { const header = table.rows[0]; for (const [index, column] of Object.entries(header.cells)) { if (index === "0") { column.createDiv({ cls: "spacer" }); const toggleButtonContainer = column.createDiv({ cls: "checkbox-toggler" }); (0, import_obsidian52.setIcon)(toggleButtonContainer, "list-todo"); } column.onclick = (e) => { if (index === "0") { const cells = table.querySelectorAll(".modifier-selector"); for (const cell of cells) { const input = cell.find("input"); if (input && !input.checkVisibility()) cell.show(); else cell.hide(); } } else { const columnId = column.querySelector("span.column-id").id; if (selectedFiles.length || allFilesSelected) processFilesFieldChange(dvTable, selectedFiles, allFilesSelected, columnId); } }; } }; var callback = function(mutationsList, dvTable) { const selectedFiles = []; let allFilesSelected = false; const filesCheckboxes = []; for (var mutation of mutationsList) { if (mutation.type == "childList") { for (const node of mutation.addedNodes) { if ("className" in node && typeof node.className === "string" && node.className.includes("dataview table-view-table")) { const table = node; cleanTable(table); for (const row of table.rows) { const cell = row.cells.item(0); if (cell) buildCellCheckBox(table, cell, filesCheckboxes, allFilesSelected, selectedFiles); } if (table.tHead) buildHeaderCols(dvTable, table, selectedFiles, allFilesSelected); } else if ("className" in node && typeof node.className === "string" && node.className.includes("internal-embed")) { const src = node.getAttr("src"); if (src && node.nodeName === "SPAN" && Object.keys(extensionMediaTypes).some((extension) => src.endsWith(extension))) { for (const child of node.childNodes) { node.removeChild(child); } const img = node.createEl("img"); img.src = dvTable.plugin.app.vault.adapter.getResourcePath(src); img.style.width = "40px"; img.style.borderRadius = "var(--image-radius)"; node.appendChild(img); } } } } else if (mutation.type == "attributes") { for (const node of mutation.addedNodes) { } } } }; const observer = new MutationObserver((mutationList) => callback(mutationList, this)); this.observers.push(observer); if (observed) observer.observe(observed, { childList: true, subtree: true }); } buildTable(tableContainer) { var _a; if (this.view instanceof FileClassTableView) this.addLinkClickEvent(tableContainer); this.buildBulkModifiers(tableContainer); tableContainer.onscroll = (e) => { var _a2; const table = tableContainer; const firstColl = tableContainer.querySelectorAll("tbody > tr > td:first-child"); const firstFileLink = (_a2 = firstColl[0]) == null ? void 0 : _a2.querySelector("a.internal-link"); if (firstColl && firstFileLink) { if (!this.firstCollWidth) this.firstCollWidth = parseFloat(getComputedStyle(firstColl[0]).width); if (!this.tableFontSize) this.tableFontSize = parseFloat(getComputedStyle(firstFileLink).width); const position = e.target.scrollLeft; if (window.matchMedia("(max-width: 400px)").matches) { if (position !== 0) { table.addClass("scrolled"); table.querySelectorAll("tbody > tr > td:first-child").forEach((item) => { item.querySelector("a:first-child").style.maxWidth = `${Math.max( 3 * this.tableFontSize, this.firstCollWidth - this.tableFontSize - position )}px`; }); } else { tableContainer.removeClass("scrolled"); table.querySelectorAll("tbody > tr > td:first-child").forEach((item) => { item.querySelector("a:first-child").style.maxWidth = "100%"; }); } } } }; const dvApi = (_a = this.plugin.app.plugins.plugins.dataview) == null ? void 0 : _a.api; if (dvApi) { dvApi.executeJs(this.buildDvJSRendering(), tableContainer, this.view.manager, this.fileClass.getClassFile().path); } } buidFileClassViewBtn() { const id = this.view.tableId; if (document.querySelector(`#${id} thead th .fileclass-icon`)) return; const firstColHeader = document.querySelector(`#${id} thead th `); if (firstColHeader instanceof Element) { firstColHeader.addClass("first-col-header-cell"); const firstColHeaderContainer = firstColHeader.createDiv({ cls: "first-col-header-container" }); [...firstColHeader.children].forEach((child) => { if (!child.hasClass("first-col-header-container")) { firstColHeaderContainer == null ? void 0 : firstColHeaderContainer.append(child); } }); const button = firstColHeaderContainer.createDiv({ cls: "fileclass-icon" }); (0, import_obsidian52.setIcon)(button, this.fileClass.getIcon()); button.onclick = () => { const fileClassViewManager = new FileClassViewManager(this.plugin, this.fileClass, "tableOption", true, this.view.selectedView); this.plugin.addChild(fileClassViewManager); fileClassViewManager.build(); }; const checkBoxContainer = firstColHeaderContainer.querySelector(".modifier-selector"); if (checkBoxContainer) firstColHeaderContainer == null ? void 0 : firstColHeaderContainer.insertAfter(button, checkBoxContainer); else firstColHeaderContainer.prepend(button); } } addClickEventToLink(link) { link.addEventListener("click", (e) => { var _a; e.preventDefault(); this.plugin.app.workspace.openLinkText( //@ts-ignore (_a = link.getAttr("data-href")) == null ? void 0 : _a.replace(/(.*).md/, "$1"), this.fileClass.getClassFile().path, "tab" ); }); } buildFilterQuery() { return Object.entries(this.viewConfiguration.filters).map(([index, filter]) => { var _a; const valueGetter = filter.name === "file" ? `p.file.name` : `p["${filter.name}"]`; const current = this.ctx ? `dv.page("${this.ctx.sourcePath}")` : "{}"; if (filter.customFilter) { return ` .filter(p => (new Function("value","current", "dv", "${filter.customFilter}"))(${valueGetter}, ${current}, dv))`; } if (filter.query) { const value = filter.query; if (!value.startsWith("/")) { let values = value.split(",").map((item) => item.trim()); const empty = values.find((v) => v === "__empty__"); const notEmpty = values.find((v) => v === "__notEmpty__"); const notFound = values.find((v) => v === "__notFound__"); const existing = values.find((v) => v === "__existing__"); values = values.filter((v) => !Object.keys(fieldStates).includes(v)); if (empty) { return ` .filter(p => hasFileClass(p.file.path, "${filter.id}") && ${valueGetter} === null) `; } else if (notEmpty) { return ` .filter(p => hasFileClass(p.file.path, "${filter.id}") && ${valueGetter} !== null) `; } else if (notFound) { return ` .filter(p => hasFileClass(p.file.path, "${filter.id}") && ${valueGetter} === undefined) `; } else if (existing) { return ` .filter(p => hasFileClass(p.file.path, "${filter.id}") && ${valueGetter} !== undefined) `; } else if (values.length) { const fCField = filter.name !== "file" ? (_a = this.plugin.fieldIndex.fileClassesFields.get(this.fileClass.name)) == null ? void 0 : _a.find((f) => f.name === filter.name) : void 0; if ((fCField == null ? void 0 : fCField.type) === "Boolean") { switch (value) { case "true": return ` .filter(p => hasFileClass(p.file.path, "${filter.id}") && ${valueGetter} === true) `; case "false": return ` .filter(p => hasFileClass(p.file.path, "${filter.id}") && ${valueGetter} === false) `; case "false, true": case "true, false": return ` .filter(p => hasFileClass(p.file.path, "${filter.id}") && [true, false].some(b => ${valueGetter} === b)) `; default: return ""; } } else { const valuesQueries = values.map((val) => `${valueGetter}.toString().toLowerCase().includes("${val}".toLowerCase())`); return ` .filter(p => hasFileClass(p.file.path, "${filter.id}") && ${valueGetter} && (${valuesQueries.join(" || ")})) `; } } else { return ""; } } else { const cleaned = value.replace(/^\//, "").replace(/\/$/, ""); let isValid = true; try { new RegExp(cleaned); } catch (error) { isValid = false; } if (isValid) return ` .filter(p => ${valueGetter} && new RegExp("${cleaned}").test(${valueGetter})) `; else return ""; } } else { return ""; } }).join(""); } buildSorterQuery() { const buildCOp = (fieldKey, cO, index, dir) => { return `rank(basename(p${index}${fieldKey}),[${cO}], ${dir})`; }; const buildOp = (fieldKey, index) => { return `basename(p${index}${fieldKey})`; }; const sorters = Object.entries(this.viewConfiguration.sorters).sort((s1, s2) => (s1[1].priority || 0) < (s2[1].priority || 0) ? -1 : 1).filter((s) => s[1].direction).map((s) => { var _a; const fieldKey = s[1].name === "file" ? `["file"]["name"]` : `["${s[1].name}"]`; const dir = s[1].direction === "asc" ? 1 : -1; if ((_a = s[1].customOrder) == null ? void 0 : _a.length) { const cO = s[1].customOrder.map((item) => `"${item}"`).join(","); return ` if(${buildCOp(fieldKey, cO, 1, dir)} > ${buildCOp(fieldKey, cO, 2, dir)}) return ${dir} if(${buildCOp(fieldKey, cO, 1, dir)} < ${buildCOp(fieldKey, cO, 2, dir)}) return ${-1 * dir} `; } else { return ` if(${buildOp(fieldKey, 1)} > ${buildOp(fieldKey, 2)}) return ${dir} if(${buildOp(fieldKey, 1)} < ${buildOp(fieldKey, 2)}) return ${-1 * dir} `; } }); const sortingQuery = ` .array().sort((p1, p2) => { ${sorters.join("")} }) `; return sortingQuery; } buildDvJSQuery() { var _a; let dvQuery = ""; const classFilesPath = this.plugin.settings.classFilesPath; const templatesFolder = (_a = this.plugin.app.plugins.plugins["templater-obsidian"]) == null ? void 0 : _a.settings["templates_folder"]; dvQuery += `dv.pages() `; dvQuery += ` .filter(p => fileClassFiles.includes(p.file.path) ${!!classFilesPath ? " && !p.file.path.includes('" + classFilesPath + "')\n" : ""} ${templatesFolder ? " && !p.file.path.includes('" + templatesFolder + "')\n" : ""} ) `; dvQuery += this.buildFilterQuery(); return dvQuery; } buildDvJSRendering() { const buildColumnName = (column) => { const hasChildren = this.viewConfiguration.children.length; if (column.name === "file") return `${this.fileClass.name}${this.count ? " (" + this.count + ")" : ""}`; const [fileClassName, fieldName] = column.id.split("____"); this.columnsFileClassField[column.id] = { fileClassName, fieldName }; return `${hasChildren ? column.id.replace("____", ": ") : column.name}`; }; const columns = this.viewConfiguration.columns.filter((f) => { var _a; return !((_a = this.viewConfiguration.columns.find((_f) => _f.id === f.id)) == null ? void 0 : _a.hidden); }).sort((f1, f2) => f1.position < f2.position ? -1 : 1); let dvJS = `const {fieldModifier: f} = MetadataMenu.api; const fFC = MetadataMenu.fieldIndex.filesFileClasses const fileClassesNames = ["${this.fileClass.name}", ...[${this.viewConfiguration.children.map((c) => "'" + c + "'").join(", ")}]]; const fileClassFiles = [...fFC.keys()].filter(path => fFC.get(path)?.some(_fileClass => fileClassesNames.includes(_fileClass.name))) const basename = (item) => { if(item && item.hasOwnProperty('path')){ return /([^/]*).md/.exec(item.path)?.[1] || item.path }else if(typeof item === 'string'){ return item }else{ const numVal = parseFloat(item?.toString()) return !isNaN(numVal) ? numVal : item?.toString() || '' } } const fileFileClasses = (path) => { return MetadataMenu.fieldIndex.filesFileClasses.get(path)?.map(_fC => _fC.name) || [] } const hasFileClass = (path, id) => { if(id.includes('____')){ const fileClassName = id.split('____')[0] return fileFileClasses(path).includes(fileClassName) } else { return true } } const rank = (item, options, dir) => { const indexInOptions = options.indexOf(basename(item)); if(dir === 1){ if(indexInOptions === -1) return Infinity } return indexInOptions } dv.table([ `; dvJS += columns.map((column) => `"${buildColumnName(column)}"`).join(","); dvJS += `], `; dvJS += this.buildDvJSQuery(); dvJS += this.buildSorterQuery(); dvJS += ` .slice(${this.sliceStart}, ${this.sliceStart + this.limit}) `; dvJS += " .map(p => [\n"; dvJS += columns.map((column) => { if (column.name === "file") { return ' dv.el("div", p.file.link, {cls: "field-name"})'; } else { return ` hasFileClass(p.file.path, "${column.id}") ? f(dv, p, "${column.name}", {options: {alwaysOn: false, showAddField: ${this.view.manager.showAddField}}}) : ""`; } }).join(",\n"); dvJS += " \n])"; dvJS += "\n);"; return dvJS; } }; // src/fileClass/views/tableViewComponents/ChildrenMultiSelectModal.ts var import_obsidian53 = require("obsidian"); var ChildrenMultiSelectModal = class extends import_obsidian53.SuggestModal { constructor(plugin, fileClass, parentFieldSet) { super(plugin.app); this.plugin = plugin; this.fileClass = fileClass; this.parentFieldSet = parentFieldSet; this.containerEl.addClass("metadata-menu"); const inputContainer = this.containerEl.createDiv({ cls: "suggester-input" }); inputContainer.appendChild(this.inputEl); this.containerEl.find(".prompt").prepend(inputContainer); cleanActions(this.containerEl, ".footer-actions"); const footerActionsContainer = this.containerEl.createDiv({ cls: "footer-actions" }); this.buildFooterActions(footerActionsContainer); const initialOptions = this.parentFieldSet.children; if (initialOptions) this.selectedChildren = [...initialOptions]; this.containerEl.onkeydown = (e) => { if (e.key == "Enter" && e.altKey) { this.parentFieldSet.reset(this.selectedChildren); this.close(); } }; } isSelected(value) { return this.selectedChildren.map((c) => c.fileClass.name).includes(value.fileClass.name); } getSuggestions(query) { const children = this.fileClass.getChildren().filter((c) => !query || c.name.toLocaleLowerCase() === query.toLocaleLowerCase()); const sortedChildren = children.sort((c1, c2) => c1.path.join(" > ") < c2.path.join(" > ") ? -1 : 1); return sortedChildren; } buildFooterActions(footerActionsContainer) { footerActionsContainer.createDiv({ cls: "spacer" }); this.buildConfirm(footerActionsContainer); const cancelButton = new import_obsidian53.ButtonComponent(footerActionsContainer); cancelButton.setIcon("cross"); cancelButton.onClick(() => this.close()); cancelButton.setTooltip("Cancel"); const clearButton = new import_obsidian53.ButtonComponent(footerActionsContainer); clearButton.setIcon("filter-x"); clearButton.setTooltip("Clear filtered value(s)"); clearButton.onClick(async () => { const fieldSet = this.parentFieldSet; const view = fieldSet.tableView; fieldSet.children = []; view.build(); view.update(); view.saveViewBtn.setCta(); this.close(); }); clearButton.buttonEl.addClass("danger"); this.modalEl.appendChild(footerActionsContainer); } buildConfirm(footerActionsContainer) { const infoContainer = footerActionsContainer.createDiv({ cls: "info" }); infoContainer.setText("Alt+Enter to save"); const confirmButton = new import_obsidian53.ButtonComponent(footerActionsContainer); confirmButton.setIcon("checkmark"); confirmButton.onClick(async () => { this.parentFieldSet.reset(this.selectedChildren); this.close(); }); } renderSelected() { const chooser = this.chooser; const suggestions = chooser.suggestions; const values = chooser.values; suggestions.forEach((s, i) => { if (this.isSelected(values[i])) { s.addClass("value-checked"); if (s.querySelectorAll(".icon-container").length == 0) { const iconContainer = s.createDiv({ cls: "icon-container" }); (0, import_obsidian53.setIcon)(iconContainer, "check-circle"); } } else { s.removeClass("value-checked"); s.querySelectorAll(".icon-container").forEach((icon) => icon.remove()); } }); } renderSuggestion(value, el) { const labelContainer = el.createDiv({ cls: "label-with-icon-container" }); const icon = labelContainer.createDiv({ cls: "icon" }); (0, import_obsidian53.setIcon)(icon, value.fileClass.getIcon()); const label = labelContainer.createDiv({ cls: "label" }); label.setText(`${value.path.join(" > ")}`); el.addClass("value-container"); const spacer = this.containerEl.createDiv({ cls: "spacer" }); el.appendChild(spacer); if (this.isSelected(value)) { el.addClass("value-checked"); const iconContainer = el.createDiv({ cls: "icon-container" }); (0, import_obsidian53.setIcon)(iconContainer, "check-circle"); } this.inputEl.focus(); } selectSuggestion(value, evt) { if (this.isSelected(value)) { const child = this.selectedChildren.find((c) => c.fileClass.name === value.fileClass.name); if (child) this.selectedChildren.remove(child); } else { this.selectedChildren.push(value); } this.renderSelected(); } onChooseSuggestion(item, evt) { } }; // src/fileClass/views/fileClassTableView.ts var FileClassTableView = class { constructor(manager, viewContainer, tableId, fileClass, selectedView) { this.manager = manager; this.viewContainer = viewContainer; this.tableId = tableId; this.fileClass = fileClass; this.selectedView = selectedView; this.limitWrapped = false; this.ranges = []; this.plugin = manager.plugin; this.container = this.viewContainer.createDiv({ cls: "fv-table" }); this.build(); } build() { this.limit = this.fileClass.getFileClassOptions().limit; this.container.replaceChildren(); this.createHeader(); this.changeView(this.selectedView, false); } createHeader() { const header = this.container.createDiv({ cls: "options" }); const limitContainer = header.createDiv({ cls: "limit" }); this.paginationContainer = header.createDiv({ cls: "pagination" }); this.fieldsContainer = header.createDiv({ cls: "fields" }); const applyContainer = header.createDiv({ cls: "footer" }); this.viewSelectContainer = applyContainer.createDiv({ cls: "cell" }); this.buildLimitManager(limitContainer); this.buildFields(this.fieldsContainer); this.buildViewSelector(); this.buildFavoriteViewManager(applyContainer); this.buildCleanFields(applyContainer); this.buildSaveView(applyContainer); this.buildSavedViewRemoveButton(applyContainer); if (this.fileClass.getChildren().length) this.buildChildrenSelector(applyContainer); this.buildHideInsertFieldBtn(applyContainer); this.buildRefreshBtn(applyContainer); this.buildHideFilters(applyContainer); } update(maxRows, sliceStart = 0) { this.manager._children.forEach((child) => this.manager.removeChild(child)); this.fileClassDataviewTable = new FileClassDataviewTable( this.fieldSet.getParams(), this, this.fileClass, maxRows, sliceStart ); for (const observer of this.fileClassDataviewTable.observers) { observer.disconnect(); } this.buildPaginationManager(this.paginationContainer); this.buildViewSelector(); this.buildTable(); } /* ** Max rows */ buildLimitManager(container) { container.replaceChildren(); container.createDiv({ text: "Results per page: ", cls: "label" }); const limitInput = new import_obsidian54.TextComponent(container); limitInput.setValue(`${this.limit}`); const debounced = (0, import_obsidian54.debounce)((fieldset) => fieldset.tableView.update(this.limit), 1e3, true); limitInput.onChange((value) => { this.limit = parseInt(value) || this.limit; this.saveViewBtn.setCta(); debounced(this.fieldSet); }); } /* ** Pagination */ buildPaginationManager(container) { this.fileClassDataviewTable.buildPaginationManager(container); } /* ** Fields */ buildFields(container) { container.replaceChildren(); this.fieldSet = new FieldSet4(this, container); } /* ** Actions */ /* view selection */ changeView(name, updateNeeded = true) { this.fieldSet.changeView(name, updateNeeded); this.selectedView = name; this.toggleFavoriteBtnState(); this.viewSelect.setValue(name || ""); this.viewRemoveBtn.setDisabled(!this.selectedView); this.viewRemoveBtn.setTooltip(`Remove ${this.selectedView} view from the saved views`); this.update(); this.saveViewBtn.removeCta(); } buildViewSelector() { this.viewSelectContainer.replaceChildren(); const options2 = this.fileClass.getFileClassOptions(); const savedViews = options2.savedViews || []; this.viewSelect = new import_obsidian54.DropdownComponent(this.viewSelectContainer); if (!savedViews.length) { this.viewSelect.addOption("", "No saved view"); this.viewSelect.setDisabled(true); } else { this.viewSelect.addOption("", "--None--"); savedViews.sort((a, b) => a.name < b.name ? -1 : 1).forEach((view) => this.viewSelect.addOption(view.name, view.name)); this.viewSelect.onChange((value) => this.changeView(value, false)); this.viewSelect.setValue(this.selectedView || ""); } } buildSavedViewRemoveButton(container) { const btnContainer = container.createDiv({ cls: "cell" }); this.viewRemoveBtn = new import_obsidian54.ButtonComponent(btnContainer).setIcon("trash").setClass("remove-button").setDisabled(!this.selectedView).setTooltip(`Remove ${this.selectedView} view from the saved views`).onClick(async () => { var _a; const options2 = this.fileClass.getFileClassOptions(); if (options2.favoriteView === this.selectedView) options2.favoriteView = null; options2.savedViews = (_a = options2.savedViews) == null ? void 0 : _a.filter((view) => view.name !== this.selectedView); await this.fileClass.updateOptions(options2); this.changeView(); this.viewRemoveBtn.setDisabled(true); this.update(); }); } toggleFavoriteBtnState() { var _a; const options2 = this.fileClass.getFileClassOptions(); const favoriteView = options2.favoriteView || null; if ((_a = options2.savedViews) == null ? void 0 : _a.length) { this.favoriteBtn.setDisabled(false); if (this.selectedView === favoriteView && !!favoriteView) { this.favoriteBtn.setTooltip("Unselect this view as your favorite view"); this.favoriteBtn.buttonEl.addClass("favorite"); } else if (this.selectedView !== void 0) { this.favoriteBtn.setTooltip("Select this view as your favorite view"); this.favoriteBtn.buttonEl.removeClass("favorite"); } else { this.favoriteBtn.setDisabled(true); this.favoriteBtn.buttonEl.removeClass("favorite"); } } else { this.favoriteBtn.setDisabled(true); this.favoriteBtn.setTooltip("You don't have any saved view yet"); } } buildFavoriteViewManager(container) { const btnContainer = container.createDiv({ cls: "cell" }); this.favoriteBtn = new import_obsidian54.ButtonComponent(btnContainer); this.favoriteBtn.setClass("favorite-button"); this.favoriteBtn.setIcon("star"); this.toggleFavoriteBtnState(); this.favoriteBtn.onClick(async () => { const options2 = this.fileClass.getFileClassOptions(); const favoriteView = options2.favoriteView || null; if (this.selectedView === favoriteView) { options2.favoriteView = null; this.favoriteBtn.buttonEl.removeClass("favorite"); } else if (this.selectedView !== void 0) { options2.favoriteView = this.selectedView; this.favoriteBtn.buttonEl.addClass("favorite"); } await this.fileClass.updateOptions(options2); this.saveViewBtn.setCta(); this.toggleFavoriteBtnState(); }); } buildCleanFields(container) { const btnContainer = container.createDiv({ cls: "cell" }); const cleanFilterBtn = new import_obsidian54.ButtonComponent(btnContainer); cleanFilterBtn.setIcon("eraser"); cleanFilterBtn.setTooltip("Clear all filters, sorters and ordering"); cleanFilterBtn.onClick(() => this.fieldSet.reset()); } buildSaveView(container) { const btnContainer = container.createDiv({ cls: "cell" }); this.saveViewBtn = new import_obsidian54.ButtonComponent(btnContainer).setIcon("save").setTooltip("Save current view (filters and sorters)").onClick(() => new CreateSavedViewModal(this.plugin, this).open()); } buildHideFilters(container) { const btnContainer = container.createDiv({ cls: "cell" }); const hideFilterBtn = new import_obsidian54.ButtonComponent(btnContainer); this.fieldsContainer.style.display = "none"; hideFilterBtn.setIcon("list-end"); hideFilterBtn.setTooltip("display filters"); const toggleState = () => { if (this.fieldsContainer.getCssPropertyValue("display") !== "none") { this.fieldsContainer.style.display = "none"; hideFilterBtn.setIcon("list-end"); hideFilterBtn.setTooltip("display filters"); } else { this.fieldsContainer.style.display = "flex"; hideFilterBtn.setIcon("list-start"); hideFilterBtn.setTooltip("collapse filters"); } }; hideFilterBtn.onClick(() => toggleState()); } buildHideInsertFieldBtn(container) { const btnContainer = container.createDiv({ cls: "cell" }); const hideInsertBtn = new import_obsidian54.ButtonComponent(btnContainer); hideInsertBtn.setIcon("plus-circle"); hideInsertBtn.setTooltip("Show insert field button in each cell (slower)"); const toggleState = () => { if (this.manager.showAddField) { hideInsertBtn.removeCta(); this.manager.showAddField = false; } else { hideInsertBtn.setCta(); this.manager.showAddField = true; } }; hideInsertBtn.onClick(() => { toggleState(); this.update(); }); } triggerRefreshNeeded() { this.refreshBtn.buttonEl.show(); this.refreshBtn.setCta(); } buildRefreshBtn(container) { const btnContainer = container.createDiv({ cls: "cell" }); this.refreshBtn = new import_obsidian54.ButtonComponent(btnContainer); this.refreshBtn.setIcon("refresh-cw"); this.refreshBtn.setTooltip("Refresh table results"); this.refreshBtn.buttonEl.hide(); this.refreshBtn.onClick(() => { this.refreshBtn.removeCta(); this.build(); this.refreshBtn.buttonEl.hide(); }); } /* ** Children selector */ buildChildrenSelector(container) { const btnContainer = container.createDiv({ cls: "cell" }); const childrenBtn = new import_obsidian54.ButtonComponent(btnContainer); childrenBtn.setIcon("network"); childrenBtn.setTooltip("display children selector"); childrenBtn.onClick(() => { new ChildrenMultiSelectModal(this.plugin, this.fileClass, this.fieldSet).open(); }); } /* ** Table */ buildTable() { if (this.tableContainer) { this.tableContainer.remove(); } ; this.tableContainer = this.container.createDiv({ attr: { id: this.tableId } }); this.fileClassDataviewTable.buildTable(this.tableContainer); } }; // src/fileClass/views/fileClassView.ts var import_promises5 = require("timers/promises"); var FILECLASS_VIEW_TYPE = "FileClassView"; var MenuOption = class { constructor(menu, id, name, relatedView, view) { this.menu = menu; this.id = id; this.name = name; this.relatedView = relatedView; this.view = view; this.itemContainer = this.menu.createDiv({ cls: "fv-menu-item", attr: { id: this.id } }); this.itemContainer.createEl("h2", { text: this.name }); this.itemContainer.onclick = () => { this.view.updateDisplayView(this.id); }; } toggleInactive() { this.itemContainer.removeClass("active"); this.relatedView.hide(); } toggleActive() { this.itemContainer.addClass("active"); this.relatedView.show(); } }; var FileClassView = class extends import_obsidian55.ItemView { constructor(leaf, plugin, tableId, component, name, fileClass, onOpenTabDisplay = "tableOption", selectedView) { super(leaf); this.leaf = leaf; this.plugin = plugin; this.tableId = tableId; this.component = component; this.name = name; this.fileClass = fileClass; this.onOpenTabDisplay = onOpenTabDisplay; this.selectedView = selectedView; this.menuOptions = []; this.views = []; this.containerEl.addClass("metadata-menu"); this.containerEl.addClass("fileclass-view"); this.contentEl.addClass("fileclass-view-content"); this.navigation = false; this.icon = "file-spreadsheet"; this.onunload = () => { this.plugin.app.viewRegistry.unregisterView(FILECLASS_VIEW_TYPE + "__" + this.fileClass.name); this.plugin.removeChild(this.component); this.unload(); }; this.buildLayout(); } updateDisplayView(id) { [...this.viewContainer.children].forEach((view) => view.hide()); this.menuOptions.forEach((option) => option.id === id ? option.toggleActive() : option.toggleInactive()); } buildLayout() { this.menu = this.contentEl.createDiv({ cls: "fv-menu" }); this.viewContainer = this.contentEl.createDiv({ cls: "view-container" }); this.buildSettingsView(); this.buildFieldsView(); this.buildTableView(); this.buildMenu(); this.updateDisplayView(this.onOpenTabDisplay); } buildMenu() { this.menuOptions.push(new MenuOption(this.menu, "tableOption", "Table view", this.tableView.container, this)); this.menuOptions.push(new MenuOption(this.menu, "fieldsOption", "Fileclass fields", this.fieldsView.container, this)); this.menuOptions.push(new MenuOption(this.menu, "settingsOption", "Fileclass settings", this.settingsView.container, this)); } buildSettingsView() { this.settingsView = new FileClassSettingsView(this.plugin, this.viewContainer, this.fileClass); this.views.push(this.settingsView.container); } buildFieldsView() { this.fieldsView = new FileClassFieldsView(this.plugin, this.viewContainer, this.fileClass); this.views.push(this.fieldsView.container); } buildTableView() { const favoriteView = this.fileClass.options.favoriteView || void 0; this.tableView = new FileClassTableView(this.component, this.viewContainer, this.tableId, this.fileClass, this.selectedView || favoriteView); this.views.push(this.tableView.container); } getDisplayText() { return this.name || "FileClass"; } getViewType() { return this.fileClass ? FILECLASS_VIEW_TYPE + "__" + this.fileClass.name : FILECLASS_VIEW_TYPE; } updateFieldsView() { this.fileClass.getAttributes(); this.fieldsView.buildSettings(); } updateSettingsView() { this.settingsView.buildSettings(); } async onOpen() { var _a; this.icon = (_a = this.fileClass) == null ? void 0 : _a.getIcon(); } }; async function openTab2(fCView, tab, speed = 100) { const menuHeader = fCView.containerEl.querySelector(`#${tab}Option`); const runner = fCView.fileClass.plugin.testRunner; if (!menuHeader) return runner.log("ERROR", `${fCView.fileClass.name} ${tab} menu not found`); menuHeader.click(); await (0, import_promises5.setTimeout)(speed); } async function testFileClassViewNavigation(plugin, fileClass, speed = 100) { const fCView = plugin.app.workspace.getActiveViewOfType(FileClassView); if (!fCView) return plugin.testRunner.log("ERROR", `${fileClass.name} view didn't open`); await openTab2(fCView, "table", speed); await openTab2(fCView, "fields", speed); await openTab2(fCView, "settings", speed); } // src/fileClass/fileClassChoiceModal.ts var import_obsidian56 = require("obsidian"); var FileClassChoiceModal = class extends import_obsidian56.SuggestModal { constructor(plugin, fileClassManager, tagsAndFileClasses) { super(plugin.app); this.plugin = plugin; this.fileClassManager = fileClassManager; this.tagsAndFileClasses = tagsAndFileClasses; this.containerEl.addClass("metadata-menu"); } getSuggestions(query) { const index = this.plugin.fieldIndex; const values = [.../* @__PURE__ */ new Set( [...index.fileClassesName.keys(), ...index.tagsMatchingFileClasses.keys()] )].filter((name) => name.toLowerCase().includes(query.toLowerCase())).sort((a, b) => a.localeCompare(b)); if (this.tagsAndFileClasses.length) { return values.filter((value) => this.tagsAndFileClasses.includes(value)); } else { return values; } } renderSuggestion(value, el) { el.setText(value); el.addClass("value-container"); } async onChooseSuggestion(item, evt) { var _a; const index = this.plugin.fieldIndex; const fileClass = index.fileClassesName.get(item) || index.tagsMatchingFileClasses.get(item); const dvApi = (_a = this.plugin.app.plugins.plugins.dataview) == null ? void 0 : _a.api; if (fileClass && dvApi) { this.fileClassManager.name = item; this.fileClassManager.fileClass = fileClass; const viewType = FILECLASS_VIEW_TYPE + "__" + fileClass.name; this.fileClassManager.fileClassViewType = viewType; await this.fileClassManager.openFileClassView(); this.plugin.indexDB.fileClassViews.editElement( viewType, { id: viewType, leafId: this.fileClassManager.fileClassView.leaf.id } ); } this.close(); } }; // src/components/FileClassViewManager.ts var FileClassViewManager = class extends import_obsidian57.Component { constructor(plugin, fileClass, onOpenTabDisplay = "tableOption", revealAfterOpen = true, selectedView) { super(); this.plugin = plugin; this.fileClass = fileClass; this.onOpenTabDisplay = onOpenTabDisplay; this.revealAfterOpen = revealAfterOpen; this.selectedView = selectedView; this.showAddField = false; if (!this.fileClass) { this.fileClassViewType = FILECLASS_VIEW_TYPE; } else { this.fileClassViewType = FILECLASS_VIEW_TYPE + "__" + this.fileClass.name; } } async openRegisterAndIndexView(fileClass) { var _a; this.fileClass = fileClass; this.name = this.fileClass.name; this.fileClassViewType = FILECLASS_VIEW_TYPE + "__" + this.fileClass.name; await this.openFileClassView(); this.registerEvent(this.plugin.app.metadataCache.on("metadata-menu:fileclass-indexed", () => { var _a2; const view = (_a2 = this.plugin.app.workspace.getLeavesOfType(this.fileClassViewType)[0]) == null ? void 0 : _a2.view; if (view) { view.updateFieldsView(); view.updateSettingsView(); view.tableView.triggerRefreshNeeded(); } })); this.plugin.indexDB.fileClassViews.editElement(this.fileClassViewType, { id: this.fileClassViewType, leafId: (_a = this.fileClassView) == null ? void 0 : _a.leaf.id }); } async build() { if (this.fileClass) this.openRegisterAndIndexView(this.fileClass); else { const tagsAndFileClasses = this.getActiveFileTagsAndFileClasses(); if (tagsAndFileClasses.length === 1) { const index = this.plugin.fieldIndex; const fileClassName = tagsAndFileClasses[0]; const fileClass = index.fileClassesName.get(fileClassName) || index.tagsMatchingFileClasses.get(fileClassName); if (fileClass) this.openRegisterAndIndexView(fileClass); else { this.plugin.removeChild(this); this.unload(); } } else { const choiceModal = new FileClassChoiceModal(this.plugin, this, tagsAndFileClasses); choiceModal.onClose = () => { if (!this.fileClass) { this.plugin.removeChild(this); this.unload(); } }; choiceModal.open(); } } } async openFileClassView() { if (this.fileClass) { const fileClass = this.fileClass; this.plugin.app.workspace.detachLeavesOfType(this.fileClassViewType); this.plugin.registerView( this.fileClassViewType, (leaf) => { this.tableId = `table-container-${Math.floor(Date.now())}`; const fileClassView = new FileClassView(leaf, this.plugin, this.tableId, this, this.name, fileClass, this.onOpenTabDisplay, this.selectedView); this.fileClassView = fileClassView; return fileClassView; } ); try { await this.plugin.app.workspace.getLeaf("tab", "vertical").setViewState({ type: this.fileClassViewType, active: true }); if (this.revealAfterOpen) { this.plugin.app.workspace.revealLeaf( this.plugin.app.workspace.getLeavesOfType(this.fileClassViewType).last() ); } } catch (e) { console.log(e); this.unload(); console.warn("Fileclass view couldn't load because of a conflict with another plugin"); } } } getActiveFileTagsAndFileClasses() { var _a, _b, _c; const index = this.plugin.fieldIndex; const activeFilePath = (_a = this.plugin.app.workspace.getActiveFile()) == null ? void 0 : _a.path; const tagsAndFileClasses = []; const dvApi = (_b = this.plugin.app.plugins.plugins.dataview) == null ? void 0 : _b.api; if (activeFilePath && activeFilePath.endsWith(".md") && dvApi) { tagsAndFileClasses.push(...((_c = dvApi.page(activeFilePath).etags) == null ? void 0 : _c.filter((tag) => [...index.tagsMatchingFileClasses.keys()].includes(tag))) || []); tagsAndFileClasses.push(...index.filesFileClassesNames.get(activeFilePath) || []); } return [...new Set(tagsAndFileClasses)]; } onunload() { this.plugin.app.workspace.detachLeavesOfType(this.fileClassViewType); this.plugin.app.viewRegistry.unregisterView(this.fileClassViewType); this.plugin.indexDB.fileClassViews.removeElement(FILECLASS_VIEW_TYPE + "__" + this.name); for (const child of this._children) { child.unload(); this.removeChild(child); } } static async reloadViews(plugin) { var _a; const registeredFileClassViews = Object.keys(plugin.app.viewRegistry.viewByType).filter((key) => key.startsWith("FileClassView__")); for (const view of await plugin.indexDB.fileClassViews.getElement("all") || []) { const fileClassName = (_a = /FileClassView__(.*)/.exec(view.id)) == null ? void 0 : _a[1]; if (fileClassName && !registeredFileClassViews.some((viewName) => viewName.includes(fileClassName))) { const leaf = plugin.app.workspace.getLeafById(view.leafId); const fileClass = plugin.fieldIndex.fileClassesName.get(fileClassName); if (fileClass) { if (leaf && !(leaf.view.component instanceof FileClassViewManager)) plugin.app.workspace.detachLeavesOfType(view.id); const fileClassManager = new FileClassViewManager(plugin, fileClass, "tableOption", false); plugin.addChild(fileClassManager); await fileClassManager.build(); } } } } }; // src/options/FileClassOptionsList.ts function isMenu(location) { return location.addItem !== void 0; } function isInsertFieldCommand(location) { return location === "InsertFieldCommand"; } function isSuggest2(location) { return location.getItems !== void 0; } var FileClassOptionsList = class { constructor(plugin, file, location, fromFile) { this.plugin = plugin; this.file = file; this.location = location; this.fromFile = fromFile; this.fileClass = this.plugin.fieldIndex.fileClassesPath.get(this.file.path); } createExtraOptionList(openAfterCreate = true) { var _a, _b; const mapWithTagAction = async () => { this.plugin.app.fileManager.processFrontMatter(this.file, (fm) => fm.mapWithTag = true); }; const openFileClassTableViewAction = () => { const fileClassComponent = new FileClassViewManager(this.plugin, fileClass); this.plugin.addChild(fileClassComponent); }; if (isMenu(this.location)) { this.location.addSeparator(); } ; const fileClass = this.fileClass; const currentFieldsNames = []; let addMissingFieldsAction = () => { new import_obsidian58.Notice("Something went wrong, please check your fileClass definitions"); }; if (this.fromFile) { const dvApi = (_a = this.plugin.app.plugins.plugins.dataview) == null ? void 0 : _a.api; if (dvApi) { const dvFile = dvApi.page(this.fromFile.path); if (dvFile) { currentFieldsNames.push(...genuineKeys(dvFile)); const modal = new chooseSectionModal( this.plugin, this.fromFile, (lineNumber, asList, asBlockquote) => insertMissingFields( this.plugin, dvFile.file.path, lineNumber, asList, asBlockquote, fileClass == null ? void 0 : fileClass.name ) ); addMissingFieldsAction = () => { modal.open(); }; } } ; } const missingFields = fileClass && this.fromFile ? !((_b = this.plugin.fieldIndex.fileClassesFields.get(fileClass.name)) == null ? void 0 : _b.map((f) => f.name).every((fieldName) => currentFieldsNames.includes(fieldName))) : false; if (isInsertFieldCommand(this.location) && fileClass) { openSettings("", fileClass.name, this.plugin); } else if (isSuggest2(this.location)) { if (fileClass) { this.location.options.push({ id: `display_table_view_for_${fileClass.name.replace("/", "_")}`, actionLabel: `Display ${fileClass.name} table view`, action: openFileClassTableViewAction, icon: "file-spreadsheet" }); } if (fileClass && !fileClass.isMappedWithTag()) { this.location.options.push({ id: "map_fileClass_with_tag", actionLabel: `Map ${fileClass.name} with tag of same name`, action: mapWithTagAction, icon: "hash" }); } if (fileClass && missingFields && this.fromFile) { this.location.options.push({ id: `insert_missig_fields_from_${fileClass.name.replace("/", "_")}`, actionLabel: `Insert missing fields from ${fileClass.name}`, action: addMissingFieldsAction, icon: "battery-full" }); } this.buildFieldOptions(); if (openAfterCreate) this.location.open(); } else if (isMenu(this.location)) { if (fileClass) { this.location.addItem((item) => { item.setTitle(`Display ${fileClass.name} table view`); item.onClick(openFileClassTableViewAction); item.setIcon("file-spreadsheet"); item.setSection(`metadata-menu-fileclass.${fileClass.name}.fileclass-fields`); }); } if (fileClass && !fileClass.isMappedWithTag()) { this.location.addItem((item) => { item.setTitle(`Map ${fileClass.name} with tag`); item.setIcon("hash"); item.onClick(mapWithTagAction); item.setSection(`metadata-menu-fileclass.${fileClass.name}.fileclass-fields`); }); } if (fileClass && missingFields && this.fromFile) { this.location.addItem((item) => { item.setTitle(`Insert missing fields from ${fileClass.name}`); item.setIcon("battery-full"); item.onClick(addMissingFieldsAction); item.setSection(`metadata-menu-fileclass.${fileClass.name}.fileclass-fields`); }); } this.buildFieldOptions(); } else { this.buildFieldOptions; } } buildFieldOptions() { var _a; (_a = this.fileClass) == null ? void 0 : _a.attributes.forEach((attr) => { if (isMenu(this.location)) { this.location.addItem((item) => { item.setTitle(`${this.fileClass.name} - ${attr.name}`); item.setIcon("wrench"); item.onClick(() => openSettings(attr.id, this.fileClass.name, this.plugin)); item.setSection(`metadata-menu-fileclass.${this.fileClass.name}.fileclass-fields`); }); } else if (isSuggest2(this.location)) { this.location.options.push({ id: `update_${attr.name}`, actionLabel: `${attr.name}`, action: () => openSettings(attr.id, this.fileClass.name, this.plugin), icon: "gear" }); } }); const action = () => openSettings("", this.fileClass.name, this.plugin); if (isMenu(this.location) && this.fileClass) { this.location.addItem((item) => { item.setTitle("Add new field"); item.setIcon("plus-circle"); item.onClick(action); item.setSection(`metadata-menu-fileclass.${this.fileClass.name}.fileclass-fields`); }); } else if (isSuggest2(this.location) && this.fileClass) { this.location.options.push({ id: "add_fileClass_attribute", actionLabel: `Insert an attribute for ${this.fileClass.name} fileClass`, action, icon: "plus-circle" }); } } }; // src/options/OptionsList.ts function isMenu2(location) { return location.addItem !== void 0; } function isInsertFieldCommand2(location) { return location === "InsertFieldCommand"; } function isSuggest3(location) { return location.getItems !== void 0; } var OptionsList = class { constructor(plugin, file, location, path = "") { this.plugin = plugin; this.file = file; this.location = location; this.path = path; this.file = file; this.location = location; } async build() { if (this.plugin.fieldIndex.isIndexed(this.file)) { this.note = await Note.buildNote(this.plugin, this.file); } } createAndOpenNodeFieldModal(node) { var _a, _b, _c; const { field: field2, value } = node; const rootNode = (_b = (_a = node == null ? void 0 : node.line) == null ? void 0 : _a.getParentLineWithField()) == null ? void 0 : _b.nodes[0]; const indexedPath = !field2 ? (rootNode == null ? void 0 : rootNode.indexedPath) || node.indexedPath : node.indexedPath; const rootField = rootNode == null ? void 0 : rootNode.field; const mField = field2 || rootField; if (mField) { const fieldVM = fieldValueManager(this.plugin, mField.id, mField.fileClassName, this.file, void 0, indexedPath); if (!fieldVM) return; fieldVM.value = value; switch (fieldVM.type) { case "Boolean": fieldVM.save(`${!fieldVM.value}`); break; case "Cycle": const nextOption = getNextOption(fieldVM); fieldVM.save(`${nextOption}`); break; default: const eF = node.line.note.getExistingFieldForIndexedPath(indexedPath); if (!eF) return; const { field: field3, file, indexedPath: _iPath, lineNumber } = eF; (_c = fieldValueManager(this.plugin, field3.id, field3.fileClassName, file, eF, _iPath, lineNumber)) == null ? void 0 : _c.openModal(); break; } } else { new import_obsidian59.Notice("No field with definition at this position", 2e3); } } createContextMenuOptionsList() { const location = this.location; if (isMenu2(location)) { location.addSeparator(); if (this.plugin.fieldIndex.isIndexed(this.file)) { this.openNoteFieldModalOption(); this.buildFieldOptionsForMenu(); this.addSectionSelectModalOption(); this.addFieldAtCurrentPositionOption(); this.addFieldAtTheEndOfFrontmatterOption(); this.addAllMissingFieldsAtSection(); } const fileClasses = this.plugin.fieldIndex.filesFileClasses.get(this.file.path) || []; fileClasses.forEach((fileClass) => { const fileClassOptionsList = new FileClassOptionsList(this.plugin, fileClass.getClassFile(), location, this.file); fileClassOptionsList.createExtraOptionList(false); }); this.addFileClassToFileOption(); this.addNewFileClassOption(); } } async createExtraOptionList(openAfterCreate = true) { var _a; await this.build(); const dvApi = (_a = this.plugin.app.plugins.plugins.dataview) == null ? void 0 : _a.api; const location = this.location; const separator2 = { id: `__optionSeparator`, actionLabel: ``, action: () => { }, icon: void 0 }; if (isInsertFieldCommand2(location)) { this.addFieldAtCurrentPositionOption(); } else if (isSuggest3(location)) { if (this.plugin.fieldIndex.isIndexed(this.file)) { this.openNoteFieldModalOption(); location.options.push(separator2); this.buildFieldOptions(); location.options.push(separator2); this.addFieldAtCurrentPositionOption(); this.addSectionSelectModalOption(); this.addFieldAtTheEndOfFrontmatterOption(); if (dvApi) { const currentFieldsNames = genuineKeys(dvApi.page(this.file.path)); if (![...this.plugin.fieldIndex.filesFields.get(this.file.path) || []].map((field2) => field2.name).every((fieldName) => currentFieldsNames.includes(fieldName))) { this.addAllMissingFieldsAtSection(); } } } const fileClasses = this.plugin.fieldIndex.filesFileClasses.get(this.file.path) || []; if (fileClasses.length) location.options.push(separator2); fileClasses.forEach((fileClass) => { const fieldCommandSuggestModal = new FieldCommandSuggestModal(this.plugin.app); const fileClassOptionsList = new FileClassOptionsList(this.plugin, fileClass.getClassFile(), fieldCommandSuggestModal, this.file); fileClassOptionsList.createExtraOptionList(false); location.options.push({ id: "manage_fileClass_attributes", actionLabel: `Manage ${fileClass.name} fileClass fields`, action: () => { fieldCommandSuggestModal.open(); }, icon: "wrench" }); }); this.addFileClassToFileOption(); this.addNewFileClassOption(); if (openAfterCreate) location.open(); } } openNoteFieldModalOption() { var _a; const lastFileClassName = (_a = this.plugin.fieldIndex.filesFileClassesNames.get(this.file.path)) == null ? void 0 : _a.last(); if (lastFileClassName) { const fileClass = this.plugin.fieldIndex.fileClassesName.get(lastFileClassName); if (fileClass) { const icon = fileClass.getIcon(); const noteFieldsComponent = new NoteFieldsComponent(this.plugin, "1", () => { }, this.file); const action = () => this.plugin.addChild(noteFieldsComponent); if (isMenu2(this.location)) { this.location.addItem((item) => { item.setTitle(`Open fields modal`); item.setIcon(icon); item.onClick(action); item.setSection("metadata-menu"); }); } else if (isSuggest3(this.location)) { this.location.options.push({ id: `open_fields_modal`, actionLabel: `Open fields modal`, action, icon }); } ; } } } buildFieldOptionsForMenu() { if (isMenu2(this.location)) { this.location.addItem((item) => { item.setIcon("clipboard-list"); item.setTitle("Manage all fields"); item.onClick(async (evt) => { const fieldCommandSuggestModal = new FieldCommandSuggestModal(this.plugin.app); const optionsList = new OptionsList(this.plugin, this.file, fieldCommandSuggestModal); await optionsList.createExtraOptionList(); }); item.setSection("metadata-menu"); }); const view = this.plugin.app.workspace.getActiveViewOfType(import_obsidian59.MarkdownView); if (view == null ? void 0 : view.editor) { const action = async () => { if (!view.file || !(view.file instanceof import_obsidian59.TFile)) return; const optionsList = new OptionsList(this.plugin, view.file, "ManageAtCursorCommand"); const note = await Note.buildNote(this.plugin, view.file); const node = note.getNodeAtPosition(view.editor.getCursor()); if (node) optionsList.createAndOpenNodeFieldModal(node); else new import_obsidian59.Notice("No field with definition at this position", 2e3); }; this.location.addItem((item) => { item.setIcon("map-pin"); item.setTitle("Manage field at cursor"); item.onClick(async () => await action()); item.setSection("metadata-menu"); }); } } } buildFieldOptions() { var _a; (_a = this.note) == null ? void 0 : _a.existingFields.filter((eF) => eF.indexedPath && upperPath(eF.indexedPath) === this.path).forEach((eF) => { const field2 = eF.field; if (field2) { const fieldVM = fieldValueManager(this.plugin, field2.id, field2.fileClassName, this.file, eF, eF.indexedPath); if (fieldVM) getActions(fieldVM == null ? void 0 : fieldVM.type)(this.plugin, field2, this.file, this.location, eF.indexedPath); } }); } addSectionSelectModalOption() { const modal = new chooseSectionModal( this.plugin, this.file, (lineNumber, asList, asBlockquote) => openFieldModal( this.plugin, this.file, void 0, lineNumber, asList, asBlockquote ) ); if (isMenu2(this.location)) { this.location.addItem((item) => { item.setIcon("enter"); item.setTitle("Add field at section..."); item.onClick((evt) => { modal.open(); }); item.setSection("metadata-menu"); }); } else if (isSuggest3(this.location)) { this.location.options.push({ id: "add_field_at_section", actionLabel: "Add field at section...", action: () => modal.open(), icon: "enter" }); } ; } addAllMissingFieldsAtSection() { const modal = new chooseSectionModal( this.plugin, this.file, (lineNumber, asList, asBlockquote) => insertMissingFields( this.plugin, this.file.path, lineNumber, asList, asBlockquote ) ); if (isMenu2(this.location)) { this.location.addItem((item) => { item.setIcon("battery-full"); item.setTitle("Add missing fields at section..."); item.onClick((evt) => { modal.open(); }); item.setSection("metadata-menu"); }); } else if (isSuggest3(this.location)) { this.location.options.push({ id: "add_missing_fields_at_section", actionLabel: "Add missing fields at section...", action: () => modal.open(), icon: "battery-full" }); } ; } addFieldAtTheEndOfFrontmatterOption() { var _a; if ((_a = this.plugin.app.metadataCache.getCache(this.file.path)) == null ? void 0 : _a.frontmatter) { if (isMenu2(this.location)) { this.location.addItem((item) => { item.setIcon("align-vertical-space-around"); item.setTitle("Add field in frontmatter"); item.onClick(async (evt) => { openFieldModal(this.plugin, this.file, void 0, -1, false, false); }); item.setSection("metadata-menu"); }); } else if (isSuggest3(this.location)) { this.location.options.push({ id: "add_field_in_frontmatter", actionLabel: "Add a field in frontmatter...", action: () => openFieldModal( this.plugin, this.file, void 0, -1, false, false ), icon: "align-vertical-space-around" }); } } } addFieldAtCurrentPositionOption() { var _a; const currentView = this.plugin.app.workspace.getActiveViewOfType(import_obsidian59.MarkdownView); const currentLineNumber = currentView == null ? void 0 : currentView.editor.getCursor().line; if (currentLineNumber !== void 0 && this.file.path == (currentView == null ? void 0 : currentView.file.path)) { const frontmatter = (_a = this.plugin.app.metadataCache.getFileCache(this.file)) == null ? void 0 : _a.frontmatter; let lineNumber = currentLineNumber; if (frontmatter) { const { start: start2, end: end2 } = getFrontmatterPosition(this.plugin, this.file); if (currentLineNumber >= start2.line && currentLineNumber < end2.line) lineNumber = -1; } if (isMenu2(this.location)) { this.location.addItem((item) => { item.setIcon("list-plus"); item.setTitle("Add field at cursor"); item.onClick((evt) => { openFieldModal( this.plugin, this.file, void 0, lineNumber, false, false ); }); item.setSection("metadata-menu"); }); } else if (isInsertFieldCommand2(this.location)) { openFieldModal( this.plugin, this.file, void 0, lineNumber, false, false ); } else if (isSuggest3(this.location)) { this.location.options.push({ id: "add_field_at_cursor", actionLabel: "Add field at cursor...", action: () => openFieldModal( this.plugin, this.file, void 0, lineNumber, false, false ), icon: "list-plus" }); } ; } } addFileClassToFileOption() { const modal = new AddFileClassToFileModal(this.plugin, this.file); const action = () => modal.open(); if (isMenu2(this.location)) { this.location.addItem((item) => { item.setIcon("plus-square"); item.setTitle(`Add ${this.plugin.settings.fileClassAlias} to ${this.file.basename}`); item.onClick(action); item.setSection("metadata-menu-fileclass"); }); } else if (isSuggest3(this.location)) { this.location.options.push({ id: "add_fileclass_to_file", actionLabel: `Add ${this.plugin.settings.fileClassAlias} to ${this.file.basename}`, action, icon: "package-plus" }); } ; } addNewFileClassOption() { const modal = new AddNewFileClassModal(this.plugin); const action = () => modal.open(); if (this.plugin.settings.classFilesPath) { if (isMenu2(this.location)) { this.location.addItem((item) => { item.setIcon("file-plus-2"); item.setTitle(`Add a new ${this.plugin.settings.fileClassAlias}`); item.onClick(action); item.setSection("metadata-menu-fileclass"); }); } else if (isSuggest3(this.location)) { this.location.options.push({ id: "add_new_fileclass", actionLabel: `Add a new ${this.plugin.settings.fileClassAlias}`, action, icon: "file-plus-2" }); } } } }; // src/fields/models/abstractModels/AbstractObject.ts var import_obsidian60 = require("obsidian"); var DefaultOptions27 = { displayTemplate: "" }; function settingsModal27(Base25) { return class SettingsModal extends Base25 { createSettingContainer() { const container = this.optionsContainer; const objectDisplayTemplateTopContainer = container.createDiv({ cls: "vstacked" }); objectDisplayTemplateTopContainer.createEl("span", { text: "Object display template", cls: "label" }); objectDisplayTemplateTopContainer.createEl("span", { text: "The number of items is referenced by the keyword 'itemsCount'", cls: "sub-text" }); const objectDisplayTemplateContainer = objectDisplayTemplateTopContainer.createDiv({ cls: "field-container" }); const objectTemplate = new import_obsidian60.TextAreaComponent(objectDisplayTemplateContainer); objectTemplate.inputEl.addClass("full-width"); objectTemplate.inputEl.cols = 50; objectTemplate.inputEl.rows = 4; objectTemplate.setValue(this.field.options.displayTemplate || ""); objectTemplate.setPlaceholder("example: {{itemsCount}} items"); objectTemplate.onChange((value) => { this.field.options.displayTemplate = value; removeValidationError(objectTemplate); }); } validateOptions() { return true; } }; } function valueModal21(managedField, plugin) { const base = basicSuggestModal(managedField, plugin); return class ValueModal extends base { constructor(...rest) { super(plugin.app); this.managedField = managedField; this.containerEl.addClass("metadata-menu"); this.containerEl.addClass("narrow"); const headerContainer = this.containerEl.createDiv({ cls: "suggester-input" }); const { id, index } = getIdAndIndex(managedField.indexedPath); if ((id == null ? void 0 : id.includes("____")) || index !== void 0) this.buildBackButton(headerContainer); this.buildTitle(headerContainer); this.inputEl.disabled = true; this.inputEl.addClass("input-as-title"); this.containerEl.find(".prompt").prepend(headerContainer); headerContainer.appendChild(this.inputEl); this.buildAddButton(headerContainer); this.containerEl.onkeydown = async (e) => { if (e.key == "Enter" && e.altKey) { e.preventDefault(); await this.onAdd(); } if (e.key == "Escape" && e.altKey) { e.preventDefault(); this.onEscape(); } }; } getSuggestions(query) { throw new Error("Method not implemented."); } renderSuggestion(value, el) { throw new Error("Method not implemented."); } onChooseSuggestion(item, evt) { throw new Error("Method not implemented."); } buildTitle(container) { var _a, _b; const titleContainer = container.createDiv({ cls: "suggester-title" }); const indexedPath = this.managedField.indexedPath || ""; const { id, index } = getIdAndIndex(indexedPath == null ? void 0 : indexedPath.split("____").last()); if (!isSingleTargeted(this.managedField)) return; if (!this.managedField.eF) { const upperPath2 = upperIndexedPathObjectPath(this.managedField.indexedPath || ""); const { id: upperId, index: upperIndex } = getIdAndIndex(upperPath2.split("____").last()); const field2 = (_a = this.managedField.plugin.fieldIndex.filesFields.get(this.managedField.target.path)) == null ? void 0 : _a.find((f) => f.id === upperId); titleContainer.setText(`${(field2 == null ? void 0 : field2.name) || "unknown"}${index ? " [" + index + "]" : ""}`); } else { if (index) { titleContainer.setText(`${this.managedField.eF.name}[${index}]`); } else { titleContainer.setText(`${(_b = this.managedField.eF) == null ? void 0 : _b.name}`); } } } buildAddButton(container) { } async onAdd() { } onEscape() { var _a; (_a = this.managedField.previousModal) == null ? void 0 : _a.open(); this.close(); } buildBackButton(container) { new import_obsidian60.ButtonComponent(container).setIcon("left-arrow").onClick(async () => { this.onEscape(); }).setCta().setTooltip("Go to parent field"); const infoContainer = container.createDiv({ cls: "info" }); infoContainer.setText("Alt+Esc to go back"); } }; } function getOptionsStr19(field2) { return field2.options.displayTemplate || ""; } async function getExistingAndMissingFields(plugin, file, indexedPath) { var _a; const existingFields = (await Note.getExistingFields(plugin, file)).filter((eF) => eF.indexedPath && upperPath(eF.indexedPath) === indexedPath); const { id, index } = getIdAndIndex(indexedPath == null ? void 0 : indexedPath.split("____").last()); const missingFields = ((_a = plugin.fieldIndex.filesFields.get(file.path)) == null ? void 0 : _a.filter((_f) => { var _a2; return ((_a2 = _f.getFirstAncestor()) == null ? void 0 : _a2.id) === id; }).filter((_f) => !existingFields.map((eF) => eF.field.id).includes(_f.id))) || []; return { existingFields, missingFields }; } function createDvField20(managedField, dv, p, fieldContainer, attrs = {}) { attrs.cls = "value-container"; const editBtn = fieldContainer.createEl("button"); managedField.value = managedField.value || {}; const value = valueString26(managedField.type)(managedField); const fieldValue = dv.el("span", value || "", attrs); fieldContainer.appendChild(fieldValue); (0, import_obsidian60.setIcon)(editBtn, getIcon(managedField.type)); editBtn.onclick = async () => { const file = managedField.plugin.app.vault.getAbstractFileByPath(p["file"]["path"]); const _eF = file instanceof import_obsidian60.TFile && await Note.getExistingFieldForIndexedPath(managedField.plugin, file, managedField.indexedPath); if (!_eF) return; managedField.eF = _eF; managedField.value = _eF.value; managedField.indexedPath = _eF.indexedPath; managedField.openModal(); }; } // src/fields/models/Object.ts var Base23 = class { constructor() { this.type = "Object"; this.tagName = "object"; this.icon = "package"; this.tooltip = "Accepts an object with nested fields"; this.colorClass = "lookup"; } }; var DefaultOptions28 = { ...DefaultOptions27, displayTemplate: "" }; function settingsModal28(Base25) { return settingsModal27(Base25); } function valueModal22(managedField, plugin) { const base = valueModal21(managedField, plugin); return class ValueModal extends base { constructor() { super(...arguments); this.existingFields = []; this.missingFields = []; } async onOpen() { if (this.managedField.indexedPath && isSingleTargeted(this.managedField)) { const { existingFields, missingFields } = await getExistingAndMissingFields( this.managedField.plugin, this.managedField.target, this.managedField.indexedPath ); this.existingFields = existingFields; this.missingFields = missingFields; } super.onOpen(); } getSuggestions(query = "") { return [...this.existingFields, ...this.missingFields].filter((f) => { if (f instanceof ExistingField2) { return f.field.name.toLocaleLowerCase().includes(query.toLocaleLowerCase()); } else { return f.name.toLocaleLowerCase().includes(query.toLocaleLowerCase()); } }); } renderSuggestion(item, el) { const container = el.createDiv({ cls: "value-container" }); if (item instanceof ExistingField2) { container.createDiv({ text: `${item.field.name} :`, cls: "label-container" }); const valueContainer = container.createDiv(); const fieldVM = fieldValueManager(this.managedField.plugin, item.field.id, item.field.fileClassName, item.file, item, item.indexedPath, item.lineNumber); fieldVM && (fieldVM == null ? void 0 : fieldVM.value) !== "" ? displayValue27(item.field.type)(fieldVM, valueContainer) : valueContainer.setText(""); } else { container.createDiv({ text: `${item.name} :`, cls: "label-container" }); container.createDiv({ text: "" }); } } async onChooseSuggestion(item, evt) { var _a, _b; const mF = this.managedField; if (!isSingleTargeted(mF)) return; if (item instanceof ExistingField2) { const cF = item.field; const cFVM = fieldValueManager(mF.plugin, cF.id, cF.fileClassName, mF.target, item, item.indexedPath, void 0, void 0, void 0, this); if (!cFVM) return; switch (item.field.type) { case "Boolean": await (cFVM == null ? void 0 : cFVM.save(`${!cFVM.value}`)); break; case "Cycle": const nextOptions = getNextOption(cFVM); await cFVM.save(`${nextOptions}`); break; default: cFVM.openModal(); break; } } else { if (item.type === "ObjectList") { await postValues(mF.plugin, [{ indexedPath: `${mF.indexedPath}____${item.id}`, payload: { value: "" } }], mF.target); this.open(); } else if (item.type === "Object") { await postValues(mF.plugin, [{ indexedPath: `${mF.indexedPath}____${item.id}`, payload: { value: "" } }], mF.target); const cF = await Note.getExistingFieldForIndexedPath(mF.plugin, mF.target, `${mF.indexedPath}____${item.id}`); (_a = fieldValueManager(mF.plugin, item.id, item.fileClassName, mF.target, cF, cF == null ? void 0 : cF.indexedPath, void 0, void 0, void 0, this)) == null ? void 0 : _a.openModal(); } else { (_b = fieldValueManager(mF.plugin, item.id, item.fileClassName, mF.target, void 0, `${mF.indexedPath}____${item.id}`, void 0, void 0, void 0, this)) == null ? void 0 : _b.openModal(); } } } }; } function valueString27(managedField) { let template = managedField.options.displayTemplate; if (!template) { const children = managedField.getChildren(); const childrenNames = children.map((c) => c.name); return childrenNames.join(", "); } else { const items = []; const defaultDisplay = (pattern) => { items.push({ pattern, value: `(${pattern}?)` }); }; const children = managedField.getChildren(); const childrenNames = children.map((c) => c.name); const templatePathRegex = new RegExp(`\\{\\{(?[^\\}]+?)\\}\\}`, "gu"); const tP = template.matchAll(templatePathRegex); let next = tP.next(); while (!next.done) { if (next.value.groups) { const pattern = next.value.groups.pattern; if (childrenNames.includes(pattern)) { const child = children.find((c) => c.name === pattern); const cFVM = fieldValueManager(managedField.plugin, child.id, child.fileClassName, managedField.target, void 0, void 0); if (!cFVM || !managedField.value) defaultDisplay(pattern); else { cFVM.value = managedField.value[child.name]; items.push({ pattern, value: valueString26(cFVM.type)(cFVM) }); } } else { defaultDisplay(pattern); } } next = tP.next(); } for (const item of items) { template = template.replace(`{{${item.pattern}}}`, item.value); } return template; } } function displayValue28(managedField, container, onClicked = () => { }) { container.setText(valueString27(managedField)); } function createDvField21(managedField, dv, p, fieldContainer, attrs = {}) { return createDvField20(managedField, dv, p, fieldContainer, attrs); } function actions23(plugin, field2, file, location, indexedPath, noteField) { const iconName = getIcon(field2.type); if (noteField) { const action = async () => await noteField.moveToObject(`${indexedPath}`); if (isFieldActions(location)) { location.addOption(`field_${field2.id}_children`, iconName, action, `Go to ${field2.name}'s fields`); } } else { const name = field2.name; const action = async () => { var _a; const note = await Note.buildNote(plugin, file); const _eF = note.existingFields.find((__eF) => __eF.indexedPath === indexedPath); if (_eF) { (_a = fieldValueManager(plugin, _eF.field.id, _eF.field.fileClassName, file, _eF, _eF.indexedPath, void 0, void 0, void 0, void 0)) == null ? void 0 : _a.openModal(); } else { const fieldCommandSuggestModal = new FieldCommandSuggestModal(plugin.app); const optionsList = new OptionsList(plugin, file, fieldCommandSuggestModal, indexedPath); await optionsList.createExtraOptionList(); } }; if (isSuggest(location)) { location.options.push({ id: `update_${name}`, actionLabel: `Update ${name}`, action, icon: iconName }); } } } function getOptionsStr20(field2) { return getOptionsStr19(field2); } function validateValue23(managedField) { return true; } function getPseudoObjectValueManagerFromObjectItem(managedField, item, previousModal) { const mF = managedField; const field2 = buildField(mF.plugin, "", "", mF.path, mF.fileClassName, void 0, void 0, void 0, "Object", {}); const itemFVM = new (FieldValueManager(mF.plugin, field2, mF.target, void 0, item.indexedPath, void 0, void 0, void 0, previousModal))(); return itemFVM; } // src/fields/models/ObjectList.ts var import_obsidian61 = require("obsidian"); var Base24 = class { constructor() { this.type = "ObjectList"; this.tooltip = "Accepts a list of object fields"; this.colorClass = "lookup"; this.tagName = "object-list"; this.icon = "boxes"; } }; var DefaultOptions29 = { ...DefaultOptions27, itemDisplayTemplate: "" }; function settingsModal29(Base25) { const base = settingsModal27(Base25); return class SettingModal extends base { constructor() { super(...arguments); this.createSettingContainer = () => { super.createSettingContainer(); const container = this.optionsContainer; const itemDisplayTemplateTopContainer = container.createDiv({ cls: "vstacked" }); itemDisplayTemplateTopContainer.createEl("span", { text: "Item display template", cls: "label" }); itemDisplayTemplateTopContainer.createEl("span", { text: "all child fields are available with their name enclosed in curly braces. Their index is referenced by the keyword 'itemIndex'", cls: "sub-text" }); const itemDisplayTemplateContainer = itemDisplayTemplateTopContainer.createDiv({ cls: "field-container" }); const template = new import_obsidian61.TextAreaComponent(itemDisplayTemplateContainer); template.inputEl.addClass("full-width"); template.inputEl.cols = 50; template.inputEl.rows = 4; template.setValue(this.field.options.itemDisplayTemplate || ""); template.setPlaceholder("example: {{itemIndex}}: {{subfieldA}} - {{subfieldC}}"); template.onChange((value) => { this.field.options.itemDisplayTemplate = value; removeValidationError(template); }); }; } validateOptions() { return true; } }; } function valueModal23(managedField, plugin) { const base = valueModal21(managedField, plugin); return class ValueModal extends base { constructor() { super(...arguments); this.objects = []; } buildAddButton(container) { const infoContainer = container.createDiv({ cls: "info" }); infoContainer.setText("Alt+Enter to Add"); const addButton = new import_obsidian61.ButtonComponent(container); addButton.setIcon("plus"); addButton.onClick(async () => { this.onAdd(); }); addButton.setCta(); addButton.setTooltip("Add a new item"); } async onAdd() { const mF = this.managedField; if (!isSingleTargeted(mF)) return; if (this.managedField.eF) { await addObjectListItem(mF); this.close(); this.open(); } else if (mF.indexedPath) { await postValues(mF.plugin, [{ indexedPath: mF.indexedPath, payload: { value: "" } }], mF.target); this.close(); this.open(); } } async onOpen() { const mF = this.managedField; if (isSingleTargeted(mF)) { const _eF = await Note.getExistingFieldForIndexedPath(mF.plugin, mF.target, mF.indexedPath); this.objects = await (_eF == null ? void 0 : _eF.getChildrenFields(mF.plugin, mF.target)) || []; } super.onOpen(); } getSuggestions(query = "") { return this.objects; } renderSuggestion(item, el) { var _a; const mF = this.managedField; const container = el.createDiv({ cls: "value-container" }); const index = container.createDiv({ cls: "index-container" }); index.setText(`${item.indexInList}`); const valueContainer = container.createDiv(); if (item.fields.length) { valueContainer.setText(displayItem(mF, (_a = mF.eF) == null ? void 0 : _a.value[item.indexInList], item.indexInList)); } else { valueContainer.setText("<--empty-->"); valueContainer.addClass("empty"); } container.createDiv({ cls: "spacer" }); const removeContainer = container.createDiv({ cls: "icon-container" }); (0, import_obsidian61.setIcon)(removeContainer, "trash"); removeContainer.onclick = () => { this.toRemove = item; }; } async onChooseSuggestion(item, evt) { const mF = this.managedField; if (!isSingleTargeted(mF)) return; const reOpen = async () => { var _a; const eF = await Note.getExistingFieldForIndexedPath(mF.plugin, mF.target, mF.indexedPath); if (eF) { (_a = fieldValueManager(mF.plugin, mF.id, mF.fileClassName, mF.target, eF, mF.indexedPath, void 0, void 0, void 0, this.managedField.previousModal)) == null ? void 0 : _a.openModal(); } }; if (this.toRemove) { const note = await Note.buildNote(mF.plugin, mF.target); if (item.indexedPath) { await note.removeObject(item.indexedPath); await reOpen(); } } else { const itemFVM = getPseudoObjectValueManagerFromObjectItem(mF, item, this); itemFVM.openModal(); } } }; } function actions24(plugin, field2, file, location, indexedPath, noteField) { const iconName = getIcon(field2.type); const name = field2.name; if (noteField) { const moveToObject = async () => await noteField.moveToObject(`${indexedPath}`); const removeObject = async () => { if (indexedPath) { const note = await Note.buildNote(plugin, file); await note.removeObject(indexedPath); } }; if (isFieldActions(location)) { location.addOption(`field_${field2.id}_goto_${indexedPath}`, iconName, moveToObject, `Go to this ${name} item`); location.addOption(`field_${field2.id}_remove_${indexedPath}`, "trash", removeObject, `Remove this ${name} item`); } } else { const moveToObject = async () => { var _a; const _eF = await Note.getExistingFieldForIndexedPath(plugin, file, indexedPath); if (_eF) (_a = fieldValueManager(plugin, _eF == null ? void 0 : _eF.field.id, _eF == null ? void 0 : _eF.field.fileClassName, file, _eF, _eF == null ? void 0 : _eF.indexedPath, void 0, void 0, void 0, void 0)) == null ? void 0 : _a.openModal(); }; const removeObject = async () => { if (indexedPath) { const note = await Note.buildNote(plugin, file); await note.removeObject(indexedPath); } }; if (isSuggest(location)) { location.options.push({ id: `update_${name}`, actionLabel: `Update ${name}`, action: moveToObject, icon: iconName }); location.options.push({ id: `remove_${name}`, actionLabel: `Remove this ${name} item`, action: removeObject, icon: "trash" }); } } } function createDvField22(managedField, dv, p, fieldContainer, attrs = {}) { return createDvField20(managedField, dv, p, fieldContainer, attrs); } function getOptionsStr21(field2) { return getOptionsStr19(field2); } function valueString28(managedField) { let template = managedField.options.displayTemplate || void 0; const itemsCount = Object.keys(managedField.value).length; if (!template) return `<${managedField.getChildren().map((f) => f.name).join(", ")}>(*${itemsCount})`; template = template.replace(`{{itemsCount}}`, `${itemsCount}`); return template; } function displayValue29(managedField, container, onClicked = () => { }) { container.setText(valueString28(managedField)); } function validateValue24(managedField) { return true; } function displayItem(managedField, value, itemIndex) { let template = managedField.options.itemDisplayTemplate || void 0; const items = []; const defaultDisplay = (pattern) => { items.push({ pattern, value: `(${pattern}?)` }); }; if (!template || !value) return `<${managedField.getChildren().map((f) => f.name).join(", ")}>[${itemIndex}]`; else { const children = managedField.getChildren(); const childrenNames = children.map((c) => c.name); const templatePathRegex = new RegExp(`\\{\\{(?[^\\}]+?)\\}\\}`, "gu"); const tP = template.matchAll(templatePathRegex); let next = tP.next(); while (!next.done) { if (next.value.groups) { const pattern = next.value.groups.pattern; if (pattern === "itemIndex") { items.push({ pattern: "itemIndex", value: `${itemIndex}` }); } else if (childrenNames.includes(pattern)) { const child = children.find((c) => c.name === pattern); const cFVM = fieldValueManager(managedField.plugin, child.id, child.fileClassName, managedField.target, void 0, void 0); if (!cFVM) defaultDisplay(pattern); else { cFVM.value = value[child.name]; items.push({ pattern, value: valueString26(cFVM.type)(cFVM) }); } } else { defaultDisplay(pattern); } } next = tP.next(); } } for (const item of items) { template = template.replace(`{{${item.pattern}}}`, item.value); } return template; } async function addObjectListItem(managedField) { const mF = managedField; const value = managedField.value; const indexForNew = !value || value.length === 0 ? 0 : value.length; if (mF.indexedPath) await postValues(mF.plugin, [{ indexedPath: `${mF.indexedPath}[${indexForNew}]`, payload: { value: "" } }], mF.target, -1); } // src/fields/Fields.ts var fieldTypes = [ "Input", "Number", "Select", "Cycle", "Boolean", "Date", "DateTime", "Time", "Multi", "File", "MultiFile", "Media", "MultiMedia", "Canvas", "CanvasGroup", "CanvasGroupLink", "Formula", "Lookup", "JSON", "YAML", "Object", "ObjectList" ]; var multiTypes = [ "Multi", "MultiFile", "MultiMedia" ]; var objectTypes = [ "Object", "ObjectList" ]; var frontmatterOnlyTypes = [ "YAML", "Object", "ObjectList" ]; var rawObjectTypes = [ "YAML", "JSON" ]; var rootOnlyTypes = [ "Canvas", "CanvasGroup", "CanvasGroupLink", "Lookup", "Formula" ]; var ReservedMultiAttributes = ["tags", "tagNames", "excludes", "aliases"]; function getDefaultOptions(type) { switch (type) { case "Input": return DefaultOptions; case "Number": return DefaultOptions2; case "Select": return DefaultOptions4; case "Cycle": return DefaultOptions7; case "Boolean": return DefaultOptions8; case "Date": return DefaultOptions10; case "DateTime": return DefaultOptions11; case "Time": return DefaultOptions12; case "Multi": return DefaultOptions6; case "File": return DefaultOptions13; case "MultiFile": return DefaultOptions14; case "Media": return DefaultOptions16; case "MultiMedia": return DefaultOptions17; case "Canvas": return DefaultOptions19; case "CanvasGroup": return DefaultOptions20; case "CanvasGroupLink": return DefaultOptions21; case "Formula": return DefaultOptions22; case "Lookup": return DefaultOptions23; case "JSON": return DefaultOptions25; case "YAML": return DefaultOptions26; case "Object": return DefaultOptions28; case "ObjectList": return DefaultOptions29; } } function getFieldSettingsModal(Field18, type, plugin, parentSetting, parentSettingContainer) { const base = buildSettingsModal(Field18, plugin, parentSetting, parentSettingContainer); switch (type) { case "Input": return new (settingsModal(base))(); case "Number": return new (settingsModal2(base))(); case "Select": return new (settingsModal4(base))(); case "Cycle": return new (settingsModal7(base))(); case "Boolean": return new (settingsModal8(base))(); case "Date": return new (settingsModal10(base))(); case "DateTime": return new (settingsModal11(base))(); case "Time": return new (settingsModal12(base))(); case "Multi": return new (settingsModal6(base))(); case "File": return new (settingsModal13(base))(); case "MultiFile": return new (settingsModal14(base))(); case "Media": return new (settingsModal16(base))(); case "MultiMedia": return new (settingsModal17(base))(); case "Canvas": return new (settingsModal19(base))(); case "CanvasGroup": return new (settingsModal20(base))(); case "CanvasGroupLink": return new (settingsModal21(base))(); case "Formula": return new (settingsModal22(base))(); case "Lookup": return new (settingsModal23(base))(); case "JSON": return new (settingsModal25(base))(); case "YAML": return new (settingsModal26(base))(); case "Object": return new (settingsModal28(base))(); case "ObjectList": return new (settingsModal29(base))(); } } function getFieldModal(managedField, plugin) { switch (managedField.type) { case "Input": return new (valueModal(managedField, plugin))(); case "Number": return new (valueModal2(managedField, plugin))(); case "Select": return new (valueModal4(managedField, plugin))(); case "Cycle": return new (valueModal7(managedField, plugin))(); case "Boolean": return new (valueModal8(managedField, plugin))(); case "Date": return new (valueModal10(managedField, plugin))(); case "DateTime": return new (valueModal11(managedField, plugin))(); case "Time": return new (valueModal12(managedField, plugin))(); case "Multi": return new (valueModal6(managedField, plugin))(); case "File": return new (valueModal13(managedField, plugin))(); case "MultiFile": return new (valueModal14(managedField, plugin))(); case "Media": return new (valueModal16(managedField, plugin))(); case "MultiMedia": return new (valueModal17(managedField, plugin))(); case "JSON": return new (valueModal19(managedField, plugin))(); case "YAML": return new (valueModal20(managedField, plugin))(); case "Object": return new (valueModal22(managedField, plugin))(); case "ObjectList": return new (valueModal23(managedField, plugin))(); default: return void 0; } } function getFieldClass(type) { switch (type) { case "Input": return Base; case "Number": return Base2; case "Select": return Base3; case "Cycle": return Base6; case "Boolean": return Base7; case "Date": return Base8; case "DateTime": return Base9; case "Time": return Base10; case "Multi": return Base5; case "File": return Base11; case "MultiFile": return Base12; case "Media": return Base14; case "MultiMedia": return Base15; case "Canvas": return Base16; case "CanvasGroup": return Base17; case "CanvasGroupLink": return Base18; case "Formula": return Base19; case "Lookup": return Base20; case "JSON": return Base21; case "YAML": return Base22; case "Object": return Base23; case "ObjectList": return Base24; } } function valueString26(type) { switch (type) { case "Input": return valueString; case "Number": return valueString2; case "Select": return valueString4; case "Cycle": return valueString7; case "Boolean": return valueString8; case "Date": return valueString10; case "DateTime": return valueString11; case "Time": return valueString12; case "Multi": return valueString6; case "File": return valueString13; case "MultiFile": return valueString14; case "Media": return valueString16; case "MultiMedia": return valueString17; case "Canvas": return valueString19; case "CanvasGroup": return valueString20; case "CanvasGroupLink": return valueString21; case "JSON": return valueString24; case "YAML": return valueString25; case "Formula": return valueString22; case "Lookup": return valueString23; case "Object": return valueString27; case "ObjectList": return valueString28; } } function displayValue27(type) { switch (type) { case "Input": return displayValue; case "Number": return displayValue2; case "Select": return displayValue4; case "Cycle": return displayValue7; case "Boolean": return displayValue8; case "Date": return displayValue10; case "DateTime": return displayValue11; case "Time": return displayValue12; case "Multi": return displayValue6; case "File": return displayValue13; case "MultiFile": return displayValue14; case "Media": return displayValue16; case "MultiMedia": return displayValue17; case "Canvas": return displayValue19; case "CanvasGroup": return displayValue20; case "CanvasGroupLink": return displayValue21; case "JSON": return displayValue24; case "YAML": return displayValue25; case "Formula": return displayValue22; case "Lookup": return displayValue23; case "Object": return displayValue28; case "ObjectList": return displayValue29; } } function getActions(type) { switch (type) { case "Input": return actions; case "Number": return actions2; case "Select": return actions4; case "Cycle": return actions7; case "Boolean": return actions8; case "Date": return actions10; case "DateTime": return actions11; case "Time": return actions12; case "Multi": return actions6; case "File": return actions13; case "MultiFile": return actions14; case "Media": return actions16; case "MultiMedia": return actions17; case "JSON": return actions21; case "YAML": return actions22; case "Formula": return actions18; case "Lookup": return actions19; case "Object": return actions23; case "ObjectList": return actions24; default: return (...rest) => { }; } } function createDvField23(managedField, dv, p, fieldContainer, attrs) { if (!managedField) return; switch (managedField.type) { case "Input": return createDvField(managedField, dv, p, fieldContainer, attrs); case "Number": return createDvField2(managedField, dv, p, fieldContainer, attrs); case "Select": return createDvField3(managedField, dv, p, fieldContainer, attrs); case "Cycle": return createDvField6(managedField, dv, p, fieldContainer, attrs); case "Boolean": return createDvField7(managedField, dv, p, fieldContainer, attrs); case "Date": return createDvField9(managedField, dv, p, fieldContainer, attrs); case "DateTime": return createDvField10(managedField, dv, p, fieldContainer, attrs); case "Time": return createDvField11(managedField, dv, p, fieldContainer, attrs); case "Multi": return createDvField5(managedField, dv, p, fieldContainer, attrs); case "File": return createDvField12(managedField, dv, p, fieldContainer, attrs); case "MultiFile": return createDvField13(managedField, dv, p, fieldContainer, attrs); case "Media": return createDvField15(managedField, dv, p, fieldContainer, attrs); case "MultiMedia": return createDvField16(managedField, dv, p, fieldContainer, attrs); case "Lookup": return createDvField17(managedField, dv, p, fieldContainer, attrs); case "JSON": return createDvField18(managedField, dv, p, fieldContainer, attrs); case "YAML": return createDvField19(managedField, dv, p, fieldContainer, attrs); case "Object": return createDvField21(managedField, dv, p, fieldContainer, attrs); case "ObjectList": return createDvField22(managedField, dv, p, fieldContainer, attrs); default: { const fieldValue = dv.el("span", managedField.value, attrs); fieldContainer.appendChild(fieldValue); } } } function getOptionStr(type) { switch (type) { case "Input": return getOptionsStr; case "Number": return getOptionsStr2; case "Select": return getOptionsStr4; case "Cycle": return getOptionsStr7; case "Boolean": return getOptionsStr8; case "Date": return getOptionsStr10; case "DateTime": return getOptionsStr11; case "Time": return getOptionsStr12; case "Multi": return getOptionsStr6; case "File": return getOptionsStr13; case "MultiFile": return getOptionsStr14; case "Media": return getOptionsStr16; case "MultiMedia": return getOptionsStr17; case "Lookup": return getOptionsStr18; case "Object": return getOptionsStr20; case "ObjectList": return getOptionsStr21; default: return () => ""; } } function validateValue25(type) { switch (type) { case "Input": return validateValue; case "Number": return validateValue2; case "Select": return validateValue3; case "Cycle": return validateValue5; case "Boolean": return validateValue6; case "Date": return validateValue8; case "DateTime": return validateValue9; case "Time": return validateValue10; case "Multi": return validateValue4; case "File": return validateValue11; case "MultiFile": return validateValue12; case "Media": return validateValue13; case "MultiMedia": return validateValue14; case "Canvas": return validateValue16; case "CanvasGroup": return validateValue17; case "CanvasGroupLink": return validateValue18; case "Formula": return validateValue19; case "Lookup": return validateValue20; case "JSON": return validateValue21; case "YAML": return validateValue22; case "Object": return validateValue23; case "ObjectList": return validateValue24; } } function getIcon(type) { const c = getFieldClass(type); return new c().icon; } function getTagName(type) { const c = getFieldClass(type); return new c().tagName; } function getTooltip(type) { const c = getFieldClass(type); return new c().tooltip; } async function getFieldSettingsTest(settingModal, field2, speed = 100) { switch (settingModal.field.type) { case "Input": await enterFieldSetting(settingModal, field2, speed); break; case "Select": await enterFieldSetting4(settingModal, field2, speed); break; case "Multi": await enterFieldSetting5(settingModal, field2, speed); break; case "Cycle": await enterFieldSetting6(settingModal, field2, speed); break; case "Number": await enterFieldSetting2(settingModal, field2, speed); break; case "Boolean": await enterFieldSetting7(settingModal, field2, speed); break; case "Date": await enterFieldSetting9(settingModal, field2, speed); break; case "DateTime": await enterFieldSetting10(settingModal, field2, speed); break; case "Time": await enterFieldSetting11(settingModal, field2, speed); break; case "File": case "MultiFile": case "Media": case "MultiMedia": case "Canvas": case "CanvasGroup": case "CanvasGroupLink": case "Formula": case "Lookup": case "JSON": case "YAML": case "Object": case "ObjectList": } } // src/modals/insertFieldSuggestModal.ts var import_obsidian62 = require("obsidian"); var defaulOptions = [ { actionLabel: "Insert missing fields in frontmatter", icon: "align-vertical-space-around" }, { actionLabel: "Insert missing fields at section", icon: "enter" } ]; var InsertFieldSuggestModal = class extends import_obsidian62.FuzzySuggestModal { // a modal to insert field at root level constructor(plugin, file, lineNumber, asList = false, asBlockquote = false) { super(plugin.app); this.plugin = plugin; this.file = file; this.lineNumber = lineNumber; this.asList = asList; this.asBlockquote = asBlockquote; this.containerEl.addClass("metadata-menu"); } getItems() { var _a, _b, _c; const { start: start2, end: end2 } = ((_a = this.plugin.app.metadataCache.getFileCache(this.file)) == null ? void 0 : _a.frontmatterPosition) || {}; if (start2 && end2 && start2.line <= this.lineNumber && end2.line >= this.lineNumber || this.lineNumber === -1) { return defaulOptions.concat( ((_b = this.plugin.fieldIndex.filesFields.get(this.file.path)) == null ? void 0 : _b.filter((_f) => _f.isRoot()).map((field2) => { return { actionLabel: field2.name, type: field2.type }; })) || [] ); } else { return defaulOptions.concat( ((_c = this.plugin.fieldIndex.filesFields.get(this.file.path)) == null ? void 0 : _c.filter((_f) => _f.isRoot() && !frontmatterOnlyTypes.includes(_f.type)).filter((_f) => !objectTypes.includes(_f.type)).map((field2) => { return { actionLabel: field2.name, type: field2.type }; })) || [] ); } } getItemText(item) { return item.actionLabel; } renderSuggestion(item, el) { el.addClass("value-container"); const iconContainer = el.createDiv({ cls: "icon-container" }); item.item.type ? (0, import_obsidian62.setIcon)(iconContainer, getIcon(item.item.type)) : (0, import_obsidian62.setIcon)(iconContainer, item.item.icon || "plus-with-circle"); el.createDiv({ text: item.item.actionLabel }); el.createDiv({ cls: "spacer" }); if (item.item.type) el.createDiv({ cls: `chip ${getTagName(item.item.type)}`, text: item.item.type }); } async onChooseItem(item, evt) { var _a, _b, _c; if (item.actionLabel === "Insert missing fields in frontmatter") { insertMissingFields(this.plugin, this.file.path, -1); } else if (item.actionLabel === "Insert missing fields at section") { new chooseSectionModal( this.plugin, this.file, (lineNumber, asList, asBlockquote) => insertMissingFields( this.plugin, this.file.path, lineNumber, asList, asBlockquote ) ).open(); } else { const field2 = (_a = this.plugin.fieldIndex.filesFields.get(this.file.path)) == null ? void 0 : _a.find((field3) => field3.name === item.actionLabel); if (field2) { if (objectTypes.includes(field2.type)) { await postValues(this.plugin, [{ indexedPath: field2.id, payload: { value: "" } }], this.file); const eF = await Note.getExistingFieldForIndexedPath(this.plugin, this.file, field2.id); (_b = fieldValueManager(this.plugin, field2.id, field2.fileClassName, this.file, eF, field2.id, void 0, void 0, void 0, void 0)) == null ? void 0 : _b.openModal(); } else { (_c = fieldValueManager(this.plugin, field2.id, field2.fileClassName, this.file, void 0, void 0, this.lineNumber, this.asList, this.asBlockquote)) == null ? void 0 : _c.openModal(); } } } } }; // src/fields/Field.ts function isFieldStyle(style) { return typeof style === "object" && Object.keys(style).every((key) => fieldDecorations.includes(FieldStyleLabel[key])); } function field(plugin, Base25, name = "", id = "", path = "", options2, fileClassName, command, display, style) { return class Field18 extends Base25 { constructor(...rest) { super(); this.plugin = plugin; if (!isFieldOptions([this.type, options2])) throw Error("This type isn't compatible with these options"); this.options = options2; this.name = name; this.id = id; this.path = path; this.fileClassName = fileClassName; this.command = command; this.display = display; this.style = style; } isRoot() { return this.path === ""; } getDisplay() { if (multiTypes.includes(this.type)) { return this.display || this.plugin.settings.frontmatterListDisplay; } else { return "asArray" /* asArray */; } } getIndexedPath(node) { var _a; if (this.path === "") return node.indexedId; const parentNode = (_a = node.line.parentLine) == null ? void 0 : _a.nodes[0]; const parentField = parentNode == null ? void 0 : parentNode.field; if (parentField) { const parentIndexedPath = parentField.getIndexedPath(parentNode); return `${parentIndexedPath}${parentIndexedPath ? "____" : ""}${node.indexedId}`; } else { return ""; } } getChildren() { var _a; if (this.fileClassName) { return ((_a = this.plugin.fieldIndex.fileClassesName.get(this.fileClassName)) == null ? void 0 : _a.attributes.map((attr) => attr.getIField()).filter((f) => !!f)).filter((f) => f.path.split("____").last() === this.id) || []; } else { return Field18.presetFields(this.plugin).filter((f) => f.path.split("____").last() === this.id); } } getFirstAncestor() { const ancestors = this.getAncestors(); return ancestors.last(); } getDottedPath() { if (!this.path) return this.name; const upperDottedPath = this.path.split("____").map((id2) => { var _a; return (_a = getField(id2, this.fileClassName, this.plugin)) == null ? void 0 : _a.name; }).join("."); return `${upperDottedPath}.${this.name}`; } hasIdAsAncestor(childId) { if (!this.path) { return false; } else { const parentId = this.path.split("____").last(); if (parentId === childId) { return true; } else { const field2 = getField(parentId, this.fileClassName, this.plugin); return (field2 == null ? void 0 : field2.hasIdAsAncestor(childId)) || false; } } } getCompatibleParents() { const otherObjectFields = this.getOtherObjectTypeFields(); if (objectTypes.includes(this.type)) { return otherObjectFields; } else { const compatibleParents = otherObjectFields.filter((_field) => { const field2 = getField(_field.id, this.fileClassName, this.plugin); return !(field2 == null ? void 0 : field2.hasIdAsAncestor(this.id)); }).filter( (_f) => !rootOnlyTypes.includes(this.type) ); return compatibleParents; } } getAncestors(fieldId = this.id) { const field2 = getField(fieldId, this.fileClassName, this.plugin); const ancestors = []; if (!field2 || !field2.path) return ancestors; const ancestorsIds = field2.path.split("____"); for (const id2 of ancestorsIds) { const ancestor = getField(id2, this.fileClassName, this.plugin); if (ancestor) ancestors.push(ancestor); } return ancestors; } getIndentationLevel(node) { const ancestors = this.getAncestors(); let level = 0; ancestors.forEach((ancestor) => { level = ancestor.type === "ObjectList" ? level + 2 : level + 1; }); if (this.isFirstItemOfObjectList(node)) level = level - 1; return level; } isFirstItemOfObjectList(node) { var _a, _b; const ancestors = this.getAncestors(this.id); if (((_a = ancestors.last()) == null ? void 0 : _a.type) === "ObjectList") { const indentRegex = new RegExp(/(?\s*)(?-\s)?.*/); const fR = node.rawContent.match(indentRegex); if ((_b = fR == null ? void 0 : fR.groups) == null ? void 0 : _b.list) { return true; } } return false; } getOtherObjectTypeFields() { var _a; let objectFields; if (this.fileClassName) { const index = this.plugin.fieldIndex; objectFields = ((_a = index.fileClassesFields.get(this.fileClassName)) == null ? void 0 : _a.filter((field2) => objectTypes.includes(field2.type) && field2.id !== this.id)) || []; } else { objectFields = this.plugin.presetFields.filter((field2) => objectTypes.includes(field2.type) && field2.id !== this.id); } return objectFields.map((f) => getField(f.id, f.fileClassName, plugin)).filter((iF) => !!iF); } validateName(textInput, contentEl) { var _a; let error = false; if (/^[#>-]/.test(this.name)) { setValidationError( textInput, "Field name cannot start with #, >, -" ); error = true; } ; if (this.name == "") { setValidationError( textInput, "Field name can not be Empty" ); error = true; } ; if (this.fileClassName) { const fields = (_a = this.plugin.fieldIndex.fileClassesFields.get(this.fileClassName)) == null ? void 0 : _a.filter((_f) => _f.path === this.path && _f.id !== this.id && _f.fileClassName === this.fileClassName); if (fields == null ? void 0 : fields.map((_f) => _f.name).includes(this.name)) { setValidationError( textInput, `There is already a field with this name for this path in this ${this.plugin.settings.fileClassAlias}. Please choose another name` ); error = true; } } else { const fields = this.plugin.presetFields.filter((_f) => _f.path === this.path && _f.id !== this.id); if (fields == null ? void 0 : fields.map((_f) => _f.name).includes(this.name)) { setValidationError( textInput, "There is already a field with this name for this path in presetFields. Please choose another name" ); error = true; } } return !error; } validateOptions() { return true; } static createDefault(plugin2, name2) { const field2 = new Field18(plugin2); field2.type = "Input"; field2.name = name2; return field2; } static presetFields(plugin2) { return plugin2.presetFields.map((prop) => { const property = new Field18(plugin2); return Object.assign(property, prop); }); } }; } function buildField(plugin, name, id, path, fileClassName, command, display, style, ...[type, options2]) { const base = getFieldClass(type); const _field = field(plugin, base, name, id, path, options2, fileClassName, command, display, style); return _field; } function buildEmptyField(plugin, fileClassName, type = "Input") { return buildField(plugin, "", "", "", fileClassName, void 0, void 0, void 0, type, getDefaultOptions(type)); } function getOptions(field2) { const options2 = field2.options; if (Object.keys(options2).length === 0 && options2.constructor === Object) { return getDefaultOptions(field2.type); } else { return field2.options; } } function getFieldConstructor(id, fileClassName, plugin) { var _a; if (fileClassName) { const index = plugin.fieldIndex; const fCF = (_a = index.fileClassesFields.get(fileClassName)) == null ? void 0 : _a.find((field2) => field2.id === id); if (!fCF) return []; if (isFieldOptions([fCF.type, fCF.options])) { const { name, id: id2, path, command, display, style, type, options: options2 } = fCF; return [buildField(plugin, name, id2, path, fileClassName, command, display, style, ...[type, options2]), type]; } } else if (id === `fileclass-field-${plugin.settings.fileClassAlias}`) { const fileClasses = [...plugin.fieldIndex.fileClassesName.keys()].sort(); const valuesList = {}; const options2 = { sourceType: "ValuesList", valuesList }; for (const [index, fC] of fileClasses.entries()) { valuesList[`${index}`] = fC; } return [buildField(plugin, plugin.settings.fileClassAlias, id, "", void 0, void 0, void 0, void 0, ...["Select", options2]), "Select"]; } else { const fS = plugin.settings.presetFields.find((f) => f.id === id); if (!fS) return []; if (isFieldOptions([fS.type, fS.options])) { const { name, id: id2, path, command, display, style, type, options: options2 } = fS; return [buildField(plugin, name, id2, path, void 0, command, display, style, ...[type, options2]), type]; } } return []; } function getField(id, fileClassName, plugin) { const [constructor] = getFieldConstructor(id, fileClassName, plugin); if (constructor) { return new constructor(); } } function copyProperty(target, source) { const unbound = (value) => value ? JSON.parse(JSON.stringify(value)) : value === "" ? "" : void 0; target.id = unbound(source.id); target.name = unbound(source.name); target.type = unbound(source.type); target.options = unbound(source.options); target.command = unbound(source.command); target.display = unbound(source.display); target.style = unbound(source.style); target.path = unbound(source.path); } function getNewFieldId(plugin) { const index = plugin.fieldIndex; const ids = []; for (const fileClassFields of index.fileClassesFields.values()) { for (const field2 of fileClassFields) { ids.push(field2.id); } } for (const field2 of plugin.presetFields) { ids.push(field2.id); } let id = browser_default({ length: 6, type: "alphanumeric" }); while (ids.includes(id)) { id = browser_default({ length: 6, type: "alphanumeric" }); } return id; } function upperIndexedPathObjectPath(indexedPath) { const endingIndex = indexedPath.match(/\[\w+\]$/); if (endingIndex) { return indexedPath.replace(/\[\w+\]$/, ""); } else { return upperPath(indexedPath); } } function upperPath(indexedPath) { const upperIndexedIds = indexedPath == null ? void 0 : indexedPath.split("____"); upperIndexedIds == null ? void 0 : upperIndexedIds.pop(); return (upperIndexedIds == null ? void 0 : upperIndexedIds.join("____")) || ""; } function getIdAndIndex(indexedId) { var _a; const { id, index } = ((_a = indexedId == null ? void 0 : indexedId.match(/(?[^\[]*)(?:\[(?.*)\])?/)) == null ? void 0 : _a.groups) || { id: "", index: void 0 }; return { id, index }; } function getValueFromIndexedPath(carriageField, obj, indexedPath) { if (!indexedPath) return obj; const plugin = carriageField.plugin; const fileClassName = carriageField.fileClassName; const indexedProps = indexedPath.split("____"); try { const indexedProp = indexedProps.shift(); const { id, index } = getIdAndIndex(indexedProp); const field2 = getField(id, fileClassName, plugin); if (!field2) return ""; let value; if (index !== void 0) { value = obj[field2.name][index]; } else { value = obj[field2.name]; } if (typeof value === "object") { const subValue = getValueFromIndexedPath(field2, value, indexedProps.join("____")); return subValue; } else if (Array.isArray(value)) { if (index && !isNaN(parseInt(index))) { const subObject = value[parseInt(index)]; const subValue = getValueFromIndexedPath(field2, subObject, indexedProps.join("____")); return subValue; } else { return value; } } else { return value; } } catch (e) { return ""; } } function isSingleTargeted(managedField) { return "target" in managedField && managedField.target instanceof import_obsidian63.TFile; } function isMultiTargeted(managedField) { const target = managedField.target; return Array.isArray(target) && target.every((t) => t instanceof import_obsidian63.TFile); } function isSuggest(location) { return location.getItems !== void 0; } function isFieldActions(location) { return location.addOption !== void 0; } function FieldValueManager(plugin, Base25, target, existingField, indexedPath, lineNumber, asList, asBlockquote, previousModal) { return class ManagedField extends Base25 { constructor(...rest) { var _a; super(plugin); this.lineNumber = -1; this.asList = false; this.asBlockquote = false; this.target = target; this.eF = existingField; this.value = (_a = this.eF) == null ? void 0 : _a.value; this.indexedPath = indexedPath; this.lineNumber = lineNumber; this.asList = asList; this.asBlockquote = asBlockquote; this.previousModal = previousModal; } openModal() { var _a; (_a = this.modal) == null ? void 0 : _a.open(); } get modal() { this._modal = getFieldModal(this, plugin); return this._modal; } async goToPreviousModal() { var _a, _b; const pM = this.previousModal; if (pM && this.indexedPath && isSingleTargeted(pM.managedField)) { const upperPath2 = upperIndexedPathObjectPath(this.indexedPath); const { index: upperFieldIndex } = getIdAndIndex(upperPath2.split("____").last()); const eF = await Note.getExistingFieldForIndexedPath(this.plugin, pM.managedField.target, pM.managedField.indexedPath); const pField = (_a = pM.managedField.eF) == null ? void 0 : _a.field; const pFile = pM.managedField.target; const pIndexedPath = pM.managedField.indexedPath; if (upperFieldIndex !== void 0 && !isNaN(parseInt(upperFieldIndex)) && isSingleTargeted(this)) { const i = parseInt(upperFieldIndex); const upperObjectListEF = await Note.getExistingFieldForIndexedPath(plugin, this.target, upperPath2.replace(/\[\d+\]$/, "")); const item = (await (upperObjectListEF == null ? void 0 : upperObjectListEF.getChildrenFields(this.plugin, this.target)) || [])[i]; const itemFVM = getPseudoObjectValueManagerFromObjectItem(this, item); itemFVM.openModal(); pM.close(); } else if (pField && pFile) { (_b = fieldValueManager( this.plugin, pField.id, pField.fileClassName, pFile, eF, pIndexedPath, pM.managedField.lineNumber, pM.managedField.asList, pM.managedField.asBlockquote, pM.managedField.previousModal )) == null ? void 0 : _b.openModal(); pM.close(); } else { pM.open(); } } this.plugin.fieldIndex.updatedManagedField = void 0; } async save(value) { if (value !== void 0) this.value = value; if (isSingleTargeted(this)) { if (this.previousModal) this.plugin.fieldIndex.updatedManagedField = this; await postValues(plugin, [{ indexedPath: this.indexedPath || this.id, payload: { value: `${this.value || ""}` } }], this.target, this.lineNumber, this.asList, this.asBlockquote); } else if (isMultiTargeted(this)) { new MultiTargetModificationConfirmModal(this).open(); } } }; } function fieldValueManager(plugin, id, fileClassName, target, existingField, indexedPath, lineNumber, asList, asBlockquote, previousModal) { const [field2] = getFieldConstructor(id, fileClassName, plugin); if (!field2) return; return new (FieldValueManager( plugin, field2, target, existingField, indexedPath, lineNumber, asList, asBlockquote, previousModal ))(); } function openFieldModal(plugin, file, fieldName, lineNumber, asList, asBlockquote) { var _a, _b; if (!fieldName) { const modal = new InsertFieldSuggestModal(plugin, file, lineNumber, asList, asBlockquote); modal.open(); } else { const field2 = (_a = plugin.fieldIndex.filesFields.get(file.path)) == null ? void 0 : _a.find((field3) => field3.name === fieldName); if (field2) { (_b = fieldValueManager(plugin, field2.id, field2.fileClassName, file, void 0, void 0, lineNumber, asList, asBlockquote)) == null ? void 0 : _b.openModal(); } } } function setValidationError(textInput, message) { textInput.inputEl.addClass("is-invalid"); const fieldContainer = textInput.inputEl.parentElement; const fieldsContainer = fieldContainer == null ? void 0 : fieldContainer.parentElement; if (message && fieldsContainer) { let mDiv = fieldsContainer.querySelector(".field-error"); if (!mDiv) mDiv = createDiv({ cls: "field-error" }); mDiv.innerText = message; fieldsContainer.insertBefore(mDiv, fieldContainer); } } function removeValidationError(textInput) { if (textInput.inputEl.hasClass("is-invalid")) textInput.inputEl.removeClass("is-invalid"); const fieldContainer = textInput.inputEl.parentElement; const fieldsContainer = fieldContainer == null ? void 0 : fieldContainer.parentElement; const fieldError = fieldsContainer == null ? void 0 : fieldsContainer.querySelector(".field-error"); if (fieldError) fieldsContainer.removeChild(fieldError); } function baseGetValueString(managedField) { let valueText; switch (managedField.value) { case void 0: valueText = ""; break; case null: valueText = ""; break; case false: valueText = "false"; break; case 0: valueText = "0"; break; default: valueText = managedField.value.toString() || ""; } return valueText; } function baseDisplayValue(managedField, container, onClicked = () => { }) { container.createDiv({ text: baseGetValueString(managedField) }); } function stringToBoolean(value) { let toBooleanValue = false; if (isBoolean(value)) { toBooleanValue = value; } else if (/true/i.test(value) || /1/.test(value)) { toBooleanValue = true; } else if (/false/i.test(value) || /0/.test(value)) { toBooleanValue = false; } ; return toBooleanValue; } // src/fields/ExistingField.ts var ExistingField2 = class { constructor(node, field2, value, indexedId, indexedPath) { this.node = node; this.field = field2; this.value = value; this.indexedId = indexedId; this.indexedPath = indexedPath; this.name = this.field.name; this.indexedId = this.indexedId || this.field.id; this.indexedPath = this.indexedPath || this.indexedId; } get lineNumber() { return this.node.line.number; } get position() { return this.node.line.position; } get file() { return this.node.line.note.file; } isRoot() { return this.field.path === ""; } async getChildrenFields(plugin, file) { if (!Array.isArray(this.value)) return []; const items = []; await Promise.all(this.value.map(async (value, index) => { const upperPath2 = `${this.indexedPath}[${index}]`; const eFields = (await Note.getExistingFields(plugin, file)).filter((eF) => eF.indexedPath && upperPath(eF.indexedPath) === upperPath2); items.push({ fields: eFields, indexInList: index, indexedPath: upperPath2 }); })); return items; } getItemDisplayForIndex(plugin, index) { if (this.field.type !== "ObjectList") return ""; let numIndex; if (typeof index === "string") { numIndex = parseInt(index); } else { numIndex = index; } if (!isNaN(numIndex) && this.field) { const item = this.value[numIndex]; const fieldVM = fieldValueManager(plugin, this.field.id, this.field.fileClassName, this.file, this, this.indexedPath); if (fieldVM) return displayItem(fieldVM, item, numIndex); } else { return `${this.name}[${index}]`; } } }; function getValueDisplay(field2) { if ((field2 == null ? void 0 : field2.value) === null) { return "<--Empty-->"; } else if (!field2) { return "<--Missing-->"; } else { return field2.value || ""; } } async function getExistingFieldForIndexedPath2(plugin, file, indexedPath) { const eFs = await Note.getExistingFields(plugin, file); return eFs.find((eF) => eF.indexedPath === indexedPath); } function getNamedIndexedPath(plugin, file, indexedPath) { const items = indexedPath.split("____"); const namedPathItems = []; const fileFields2 = plugin.fieldIndex.filesFields.get(file.path) || []; for (const item of items) { const { id, index } = getIdAndIndex(item); const field2 = fileFields2.find((f) => f.id === id); if (!field2) return; namedPathItems.push(`${field2.name}${index ? "[" + index + "]" : ""}`); } return namedPathItems.join("____"); } // src/note/lineNode.ts var separator = { "yaml": ":", "inline": "::" }; var enclosure = { "brackets": { start: "[", end: "]" }, "parenthesis": { start: "(", end: ")" } }; var LineNode = class { constructor(plugin, line, rawContent = "", indentationLevel = 0, index = 0, field2, value, parsedField2, blockquote = "") { this.plugin = plugin; this.line = line; this.rawContent = rawContent; this.indentationLevel = indentationLevel; this.index = index; this.field = field2; this.value = value; this.parsedField = parsedField2; this.blockquote = blockquote; this.buildDecoratedFieldName = () => { if (!this.field) return ""; let level = this.field.getIndentationLevel(this); switch (this.line.position) { case "yaml": const _ = this.field.isFirstItemOfObjectList(this) ? "- " : ""; return `${" ".repeat(level)}${_}${this.field.name}`; case "inline": { const targetStartStyle = buildStartStyle(this.field.style || {}); const targetEndStyle = buildEndStyle(this.field.style || {}); return `${this.blockquote}${" ".repeat(this.indentationLevel)}${this.line.isNewListItem ? "- " : ""}${targetStartStyle}${this.field.name}${targetEndStyle}`; } } }; this.buildIndentedListItem = (value, shift = 0) => { if (!this.field) return ""; const ancestors = this.field.getAncestors(); const level = ancestors.map((a) => a.type === "ObjectList" ? 2 : 1).reduce((p, c) => p + c, 0); return `${" ".repeat(level + 1 + shift)}- ${value}`; }; this.removeIndentedListItems = () => { if (!this.field || !(this.field.type === "JSON" || this.field.type === "YAML" || this.field.type === "Lookup" || this.field.type === "Multi" || this.field.type === "MultiFile" || this.field.type === "MultiMedia" || this.field.type === "Canvas" || this.field.type === "CanvasGroup" || this.field.type === "CanvasGroupLink")) return; if (this.line.position === "inline" && this.field.type !== "Lookup") return; const indentLevel = this.field.getAncestors().length; const nextLines = this.line.note.lines.filter((_line) => _line.number > this.line.number); for (const line of nextLines) { if (line.rawContent.startsWith(" ".repeat(indentLevel + 1))) { line.removeLineFromNote(); } else { break; } } }; if (this.line.shouldParse) { const nodeRegex = new RegExp(/(?
\>*)(?\s*)(?-\s)?(?.*)/); const parsedContent = this.rawContent.match(nodeRegex); this.defineLinePrefixAttributes(parsedContent); this.defineExistingFieldsAndValues(parsedContent); } this.line.nodes.push(this); } defineLinePrefixAttributes(parsedContent) { if (parsedContent == null ? void 0 : parsedContent.groups) { if (parsedContent.groups.indentation) { this.indentationLevel = parsedContent.groups.indentation.length / 2; if (parsedContent.groups.list) { this.indentationLevel += 1; } } this.line.isNewListItem = !!parsedContent.groups.list; this.blockquote = parsedContent.groups.blockquote || ""; } this.line.indentationLevel = this.indentationLevel; if (this.indentationLevel) { const parentLine = this.line.note.lines.filter( (line) => line.number < this.line.number && line.indentationLevel < this.line.indentationLevel ).last(); this.line.parentLine = parentLine; } } defineExistingFieldsAndValues(parsedContent) { var _a; const frontmatter = this.line.note.frontmatter || {}; const field2 = this.field; switch (this.line.position) { case "yaml": { const { attribute: yamlAttr, values: value } = frontMatterLineField(this.rawContent); if (!yamlAttr && this.line.isNewListItem) { const parentLine = this.line.parentLine; const parentNode = parentLine == null ? void 0 : parentLine.nodes[0]; const parentField = parentNode == null ? void 0 : parentNode.field; if ((parentField == null ? void 0 : parentField.type) === "ObjectList" || (parentField == null ? void 0 : parentField.type) === "Lookup" && bulletListLookupTypes.includes(parentField.options.outputType)) { const objectListLines = parentLine.objectListLines; objectListLines.push([this.line]); const index = objectListLines.length - 1; this.indexedId = ""; this.indexedPath = `${parentNode == null ? void 0 : parentNode.indexedPath}[${index}]`; this.value = ""; } } for (const field3 of this.line.note.fields) { if (yamlAttr === field3.name) { let indexedId = field3.id; if (this.line.parentLine) { const parentNode = this.line.parentLine.nodes[0]; const parentField = parentNode.field; if (parentField) { const parentIndexedId = (_a = this.line.note.existingFields.find((eF) => eF.field.id === parentField.id)) == null ? void 0 : _a.indexedId; indexedId = `${parentIndexedId}____${field3.id}` || field3.id; } else { indexedId = field3.id; } } else { indexedId = field3.id; } if (field3.path && indexedId !== `${field3.path}____${field3.id}`) continue; this.indexedId = indexedId; const existingField = new ExistingField2(this, field3, this.value, this.indexedId); if (field3.path) { const parentLine = this.line.parentLine; const parentNode = parentLine == null ? void 0 : parentLine.nodes[0]; const parentField = parentNode == null ? void 0 : parentNode.field; if ((parentField == null ? void 0 : parentField.id) === field3.path.split("____").last()) { this.field = field3; if (this.field && (parentField == null ? void 0 : parentField.type) === "ObjectList") { const objectListLines = parentLine.objectListLines; if (this.line.isNewListItem) { objectListLines.push([this.line]); } else { const lastObject = objectListLines.last(); lastObject == null ? void 0 : lastObject.push(this.line); } const index = objectListLines.length - 1; this.indexedPath = `${parentNode == null ? void 0 : parentNode.indexedPath}[${index}]____${this.field.id}`; } else { this.indexedPath = `${parentNode == null ? void 0 : parentNode.indexedPath}____${this.field.id}`; } this.value = getValueFromIndexedPath(this.field, this.line.note.frontmatter, this.indexedPath); existingField.value = this.value; existingField.indexedId = this.indexedId; existingField.indexedPath = this.indexedPath; this.line.note.existingFields.push(existingField); break; } else if (!parentField) { this.field = field3; this.indexedPath = this.field.getIndexedPath(this); } else { break; } } else if (field3.id === indexedId) { this.field = field3; this.indexedPath = this.field.getIndexedPath(this); this.value = frontmatter[field3.name]; existingField.value = this.value; this.line.note.existingFields.push(existingField); break; } } } if (yamlAttr === this.plugin.settings.fileClassAlias) { const fileClasses = [...this.plugin.fieldIndex.fileClassesName.keys()].sort(); const fileClassField = new (buildEmptyField(this.plugin, void 0, "Select"))(); const valuesList = {}; const options2 = { sourceType: "ValuesList", valuesList }; for (const [index, fC] of fileClasses.entries()) { valuesList[`${index}`] = fC; } fileClassField.options = options2; fileClassField.id = `fileclass-field-${this.plugin.settings.fileClassAlias}`; fileClassField.name = this.plugin.settings.fileClassAlias; this.field = fileClassField; this.indexedPath = fileClassField.id; this.value = value; const existingField = new ExistingField2(this, fileClassField, value, this.field.id); this.line.note.existingFields.push(existingField); } } break; case "inline": { if (field2 && !frontmatterOnlyTypes.includes(field2.type)) { const existingField = new ExistingField2(this, field2, this.value, field2.id); this.indexedId = field2.id; this.indexedPath = field2.getIndexedPath(this); this.line.note.existingFields.push(existingField); } else if (this.line.isNewListItem) { const parentLine = this.line.parentLine; const parentNode = parentLine == null ? void 0 : parentLine.nodes[0]; const parentField = parentNode == null ? void 0 : parentNode.field; if (parentField && (parentField == null ? void 0 : parentField.type) === "Lookup" && bulletListLookupTypes.includes(parentField.options.outputType)) { const objectListLines = parentLine.objectListLines; objectListLines.push([this.line]); this.indexedId = ""; this.value = ""; const eF = parentLine.note.getExistingFieldForIndexedPath(parentField.id); if (eF) { if ((parsedContent == null ? void 0 : parsedContent.groups) && parsedContent.groups.value) { eF.value = [...eF.value || [], parsedContent.groups.value]; } } } } } break; } } wrapField(content) { if (this.parsedField) { const enclosureType = this.parsedField.enclosureType; if (enclosureType) { const start2 = enclosure[enclosureType].start; const end2 = enclosure[enclosureType].end; return `${start2}${content}${end2}`; } } return content; } createFieldNodeContent(field2, value, location, asList = false, asBlockquote = false) { const _ = separator[location]; this.field = field2; let content; if (this.field) { const fieldHeader = this.buildDecoratedFieldName(); const newValue = this.line.note.renderFieldValue(this.field, value, location); this.removeIndentedListItems(); if (Array.isArray(newValue)) { if (this.field.getDisplay() === "asList" /* asList */ || this.field.type === "Lookup" && bulletListLookupTypes.includes(this.field.options.outputType)) { content = `${fieldHeader}${_}`; newValue.filter((v) => !!v).reverse().forEach((item, i) => { const newItemLine = new Line(this.plugin, this.line.note, location, "", this.line.number + 1); new LineNode(this.plugin, newItemLine, this.buildIndentedListItem(item)); newItemLine.renderLine(asList, asBlockquote); }); } else { content = `${fieldHeader}${_} [${newValue.join(", ")}]`; } } else { content = `${fieldHeader}${_} ${newValue}`; if (this.field.type === "ObjectList") { const newItemLine = new Line(this.plugin, this.line.note, location, "", this.line.number + 1); new LineNode(this.plugin, newItemLine, this.buildIndentedListItem("", 1)); newItemLine.renderLine(asList, asBlockquote); } } } else { content = `${field2.name}${_} ${value}`; } if (location === "inline") { this.rawContent = this.wrapField(content); } else { this.rawContent = content; } } }; // src/note/line.ts var positionIcon = { yaml: "align-vertical-space-around", inline: "log-in" }; var Line = class { constructor(plugin, note, position, rawContent = "", number, indentationLevel = 0, shouldParse = true) { this.plugin = plugin; this.note = note; this.position = position; this.rawContent = rawContent; this.number = number; this.indentationLevel = indentationLevel; this.shouldParse = shouldParse; this.nodes = []; this.objectListLines = []; this.isNewListItem = false; this.buildNodes(); this.insertLineInNote(); } buildNodes() { if (!(this.position === "yaml") && this.plugin.settings.frontmatterOnly) { new LineNode(this.plugin, this, this.rawContent); return; } if (this.note.codeBlocksLines.includes(this.number)) this.shouldParse = false; if (!(this.position === "yaml") && !this.note.prefixedLines.includes(this.number) && !this.note.inlineFieldsLines.includes(this.number)) this.shouldParse = false; if (!this.shouldParse) { new LineNode(this.plugin, this, this.rawContent); return; } switch (this.position) { case "yaml": new LineNode(this.plugin, this, this.rawContent); break; case "inline": const fields = getLineFields(this.rawContent); const nodesIndexes = [0]; for (const field2 of fields) { const fieldIndex = field2.index; const nextNodeIndex = field2.index + field2.length; if (nodesIndexes.indexOf(fieldIndex) === -1) nodesIndexes.push(fieldIndex); nodesIndexes.push(nextNodeIndex); } for (const index of nodesIndexes) { const parsedField2 = fields.find((_field) => _field.index === index); if (parsedField2) { const start2 = parsedField2.index; const end2 = start2 + parsedField2.length; const _field = this.note.getFieldFromNameAndPath(parsedField2.attribute); const field2 = _field && !frontmatterOnlyTypes.includes(_field.type) ? _field : void 0; new LineNode(this.plugin, this, this.rawContent.slice(start2, end2), 0, index, field2, parsedField2.values, parsedField2); } else { const nextIndex = nodesIndexes[nodesIndexes.indexOf(index) + 1] || this.rawContent.length; const content = this.rawContent.slice(index, nextIndex); if (content) new LineNode(this.plugin, this, content, 0, index); } } break; } } getParentLineWithField() { if (this.parentLine) { if (!this.parentLine.nodes.some((node) => !!node.field)) { return this.parentLine.getParentLineWithField(); } else { return this.parentLine; } } else { if (this.nodes.some((node) => !!node.field)) return this; } } removeLineFromNote() { for (const _line of this.note.lines) { if (_line.number && _line.number >= this.number) { _line.number -= 1; } } this.nodes = []; this.note.lines.remove(this); } getLastChildLine() { var _a, _b; let lastChildLine = this; for (const line of this.note.lines.filter((_l) => _l.number > this.number)) { if (line.indentationLevel === 0) break; if (line.indentationLevel > this.indentationLevel || line.indentationLevel === this.indentationLevel && ((_b = (_a = line.nodes[0]) == null ? void 0 : _a.field) == null ? void 0 : _b.type) === "ObjectList" && !line.isNewListItem) { lastChildLine = line; } else { break; } } return lastChildLine; } insertLineInNote() { for (const _line of this.note.lines) { if (_line.number && _line.number >= this.number) { _line.number += 1; } } this.note.lines.splice(this.number, 0, this); } renderLine(asList = false, asBlockquote = false) { const rawContent = this.nodes.map((node) => node.rawContent).join(""); this.rawContent = `${asBlockquote ? ">" : ""}${asList ? "- " : ""}${rawContent}`; } }; // src/utils/mediaUtils.ts function renderMediaItem(location, filename, field2) { const { embed, thumbnailSize } = field2.options; const extension = filename.split(".").last(); if (!extension) return ""; const alias = extensionMediaTypes[extension] === "Image" /* Image */ ? thumbnailSize : void 0; switch (location) { case "yaml": return `[[${filename}]]`; case "inline": return `${embed ? "!" : ""}[[${filename}${alias ? "|" + alias : ""}]]`; } } // src/note/note.ts var Note = class { constructor(plugin, file) { this.plugin = plugin; this.file = file; this.lines = []; this.fields = []; this.existingFields = []; this.codeBlocksLines = []; this.inlineFieldsLines = []; this.prefixedLines = []; this.renderMultiFields = (rawValue, itemRendering) => { const values = rawValue.replace(/(\,\s+)/g, ",").split(",").filter((v) => !!v).map((value) => itemRendering(value)); return values.length ? values : ""; }; this.renderMultiFilesFields = (rawValue, itemRendering) => { const values = (rawValue.match(/\!?\[(?:\[??[^\[]*?\]\])/g) || []).map((value) => itemRendering(value)); return (values == null ? void 0 : values.length) ? values : ""; }; this.createLine = (value, position, lineNumber, field2, asList = false, asBlockquote = false) => { const newLine = new Line(this.plugin, this, position, "", lineNumber); const newNode = new LineNode(this.plugin, newLine); if (field2) newNode.createFieldNodeContent(field2, value, position); newLine.renderLine(asList, asBlockquote); }; this.fields = this.plugin.fieldIndex.filesFields.get(this.file.path) || []; } getField(id) { return this.fields.find((field2) => field2.id === id); } getFieldFromNameAndPath(name, path = "") { return this.fields.find((field2) => field2.name === name && field2.path === path); } renderValueString(_rawValue, fieldType, indentationLevel = 0) { if (_rawValue) { if (_rawValue.startsWith("[[") || _rawValue.startsWith("![[")) { return `"${_rawValue}"`; } else if (_rawValue.startsWith("#")) { return `${_rawValue}`; } else if (fieldType && rawObjectTypes.includes(fieldType)) { const indentation = ` ${" ".repeat(indentationLevel + 1)}`; return `${indentation}${_rawValue.split("\n").join(indentation)}`; } else { return [_rawValue, true, false].includes((0, import_obsidian64.parseYaml)(_rawValue)) || !isNaN(parseFloat(_rawValue)) ? (0, import_obsidian64.parseYaml)(_rawValue) : `"${_rawValue}"`; } ; } else { return ""; } } renderFieldValue(field2, rawValue, location) { const type = field2 == null ? void 0 : field2.type; const indentationLevel = (field2 == null ? void 0 : field2.path) ? field2.path.split("____").length : 0; switch (location) { case "yaml": switch (type) { case "Lookup": { if ([ "BuiltinSummarizing", "CustomSummarizing" ].includes(field2.options.outputType)) { return this.renderValueString(rawValue, type, indentationLevel); } else { return this.renderMultiFilesFields(rawValue, (item) => this.renderValueString(item, type, indentationLevel)); } } ; case "Media": return `"${renderMediaItem("yaml", rawValue, field2)}"`; case "Multi": return this.renderMultiFields(rawValue, (item) => this.renderValueString(item, type, indentationLevel)); case "MultiFile": return this.renderMultiFilesFields(rawValue, (item) => `"${item}"`); ; case "MultiMedia": return this.renderMultiFields(rawValue, (item) => `"${renderMediaItem("yaml", item, field2)}"`); case "Canvas": return this.renderMultiFilesFields(rawValue, (item) => item ? `"${item}"` : ""); case "CanvasGroup": return this.renderMultiFields(rawValue, (item) => this.renderValueString(item, type, indentationLevel)); case "CanvasGroupLink": return this.renderMultiFilesFields(rawValue, (item) => item ? `"${item}"` : ""); case void 0: if ([...ReservedMultiAttributes, this.plugin.settings.fileClassAlias].includes(field2.name)) { return this.renderMultiFields(rawValue, (item) => `${item}`); } else { return this.renderValueString(rawValue, type, indentationLevel); } ; default: return this.renderValueString(rawValue, type, indentationLevel); } case "inline": switch (type) { case "Media": return renderMediaItem("inline", rawValue, field2); case "MultiMedia": return rawValue.split(",").filter((v) => !!v).map((v) => v.trim()).map((v) => renderMediaItem("inline", v, field2)).join(", "); case "Lookup": { if (field2 && bulletListLookupTypes.includes(field2.options.outputType)) { return this.renderMultiFields(rawValue, (item) => item); } else { return rawValue; } } case "JSON": return JSON.stringify(JSON.parse(rawValue || "{}")); case "YAML": { return dumpValue(rawValue); } default: return rawValue; } } } buildSections(content) { var _a, _b; const yamlLines = []; let inFrontmatter = false; let inStartingBlankLines = false; let frontmatterStart; let frontmatterEnd; let startsWithText = false; let previousLineIsCode = false; for (const [i, rawLine] of content.split("\n").entries()) { if (frontmatterEnd === void 0) { if (!inFrontmatter) { if (rawLine.trim() === "") inStartingBlankLines = true; else if (!((_a = this.frontmatterPosition) == null ? void 0 : _a.end.line) && rawLine !== "---") startsWithText = true; } if (!startsWithText) { if (!inFrontmatter && !((_b = this.frontmatterPosition) == null ? void 0 : _b.end.line) && rawLine === "---" && (inStartingBlankLines || i === 0)) { inFrontmatter = true; inStartingBlankLines = false; frontmatterStart = { line: i }; } else if (inFrontmatter) { if (rawLine === "---") { inFrontmatter = false; frontmatterEnd = { line: i }; } else { yamlLines.push(rawLine); } } } } if (!inFrontmatter) { if (this.plugin.settings.frontmatterOnly) break; if (rawLine.startsWith("```")) { this.codeBlocksLines.push(i); previousLineIsCode = !previousLineIsCode; } else if (previousLineIsCode) { this.codeBlocksLines.push(i); } else { if (rawLine.includes("::")) this.inlineFieldsLines.push(i); if ([" ", "-", ">", "*", "~", "_", "`"].some((prefix) => rawLine.startsWith(prefix))) this.prefixedLines.push(i); } } } try { this.frontmatter = yamlLines.length ? (0, import_obsidian64.parseYaml)(yamlLines.join("\n")) : void 0; if (frontmatterStart && frontmatterEnd) this.frontmatterPosition = { start: frontmatterStart, end: frontmatterEnd }; } catch (error) { this.frontmatterPosition = void 0; } } async build() { const content = await this.plugin.app.vault.read(this.file); const lines = content.split("\n"); this.buildSections(content); const frontmatterEnd = this.frontmatterEnd(); for (const [i, rawLine] of lines.entries()) { const position = !!frontmatterEnd && i <= frontmatterEnd ? "yaml" : "inline"; new Line(this.plugin, this, position, rawLine, i); } } getExistingFieldForIndexedPath(indexedPath) { return this.existingFields.find((eF) => eF.indexedPath === indexedPath); } getNodeForIndexedPath(indexedPath) { for (const line of this.lines) { const node = line.nodes.find((_node) => _node.indexedPath === indexedPath); if (node) return node; } return void 0; } getNodeAtPosition(position) { var _a; const { ch: cursor, line: lineNumber } = position; const nodes = ((_a = this.lines.find((line) => line.number === lineNumber)) == null ? void 0 : _a.nodes) || []; nodes.sort((a, b) => a.index - b.index); for (const node of nodes) { if (node.index <= cursor && cursor <= node.rawContent.length + node.index) return node; } return; } frontmatterEnd() { var _a; return (_a = this.frontmatterPosition) == null ? void 0 : _a.end.line; } initFrontmatter() { new Line(this.plugin, this, "yaml", "---", 0); new Line(this.plugin, this, "yaml", "---", 0); this.frontmatter = {}; this.frontmatterPosition = { start: { line: 0 }, end: { line: 1 } }; } insertField(indexedPath, payload, lineNumber, asList = false, asBlockquote = false) { var _a, _b, _c, _d, _e; const upperPath2 = upperIndexedPathObjectPath(indexedPath); const { id, index } = getIdAndIndex(indexedPath.split("____").last()); const { id: upperFieldId, index: upperFieldIndex } = getIdAndIndex(upperPath2.split("____").last()); if (lineNumber === -1 && !this.frontmatter) this.initFrontmatter(); if (id.startsWith("fileclass-field")) { const fR = id.match(/fileclass-field-(?.*)/); if ((_a = fR == null ? void 0 : fR.groups) == null ? void 0 : _a.fileClassAlias) { const content = `${fR.groups.fileClassAlias}: ${payload.value}`; const newLine = new Line(this.plugin, this, "yaml", content, 1); newLine.renderLine(asList, asBlockquote); } return; } if (!upperFieldIndex) { const field2 = this.getField(id); if (!field2) return; if (frontmatterOnlyTypes.includes(field2.type) && !this.frontmatter) this.initFrontmatter(); const frontmatterEnd = this.frontmatterEnd(); let insertLineNumber = lineNumber === 0 ? 0 : (lineNumber !== void 0 ? Math.max(lineNumber, 0) : void 0) || frontmatterEnd || ((_b = this.lines.last()) == null ? void 0 : _b.number) || 0; if (frontmatterOnlyTypes.includes(field2.type)) insertLineNumber = frontmatterEnd; const position = frontmatterEnd && insertLineNumber <= frontmatterEnd ? "yaml" : "inline"; if (field2.type !== "ObjectList") { const parentField = this.existingFields.find((eF) => eF.indexedPath === upperPath2); if ((parentField == null ? void 0 : parentField.field.type) === "Object") { const parentLine = (_c = this.getNodeForIndexedPath(upperPath2)) == null ? void 0 : _c.line; const lastChildLine = parentLine == null ? void 0 : parentLine.getLastChildLine(); this.createLine(payload.value, "yaml", lastChildLine ? lastChildLine.number + 1 : 1, field2, asList, asBlockquote); } else { this.createLine(payload.value, position, insertLineNumber, field2, asList, asBlockquote); } } else { const upperNode = this.getNodeForIndexedPath(upperPath2); if (!upperNode) { const objectListHeaderLine = new Line(this.plugin, this, position, `${field2.name}:`, insertLineNumber); objectListHeaderLine.renderLine(); } else { if (((_d = upperNode.field) == null ? void 0 : _d.id) !== field2.id) { const objectListHeaderLine = new Line(this.plugin, this, position, "", upperNode.line.number + 1); const node = new LineNode(this.plugin, objectListHeaderLine, ""); node.createFieldNodeContent(field2, "", "yaml"); node.line.renderLine(); } else { const newItemLine = new Line(this.plugin, upperNode.line.note, position, "", upperNode.line.number + 1); new LineNode(this.plugin, newItemLine, upperNode.buildIndentedListItem("")); newItemLine.renderLine(); } } } } else { const i = parseInt(upperFieldIndex); const parentFieldIndexedPath = upperPath2.replace(/\[\w+\]$/, ""); const parentNode = this.getNodeForIndexedPath(parentFieldIndexedPath); if (!parentNode) { new import_obsidian64.Notice("A parent field is missing, this field can't be added"); return; } const field2 = this.getField(id); const lastItemLine = parentNode.line.objectListLines[i].last(); if (lastItemLine) { if (/-(\s+)?$/.test(((_e = parentNode.line.objectListLines[i].last()) == null ? void 0 : _e.rawContent) || "") && field2) { const node = lastItemLine.nodes[0]; node.createFieldNodeContent(field2, payload.value, "yaml"); node.line.renderLine(asList, asBlockquote); } else { const lastChildLine = lastItemLine.getLastChildLine(); this.createLine(payload.value, "yaml", lastChildLine ? lastChildLine.number + 1 : 1, field2, asList, asBlockquote); } } } } async removeObject(indexedPath) { const nodes = this.lines.map((_l) => _l.nodes.filter((_n) => { var _a; return (_a = _n.indexedPath) == null ? void 0 : _a.startsWith(indexedPath); })).flat(Infinity); nodes.map((_n) => _n.line.removeLineFromNote()); await this.plugin.app.vault.modify(this.file, this.renderNote()); } async createOrUpdateFields(fields, lineNumber, asList = false, asBlockquote = false) { fields.forEach((field2) => { const node = this.getNodeForIndexedPath(field2.indexedPath); if (node && node.field) { node.createFieldNodeContent(node.field, field2.payload.value, node.line.position, asList, asBlockquote); node.line.renderLine(asList, asBlockquote); } else { this.insertField(field2.indexedPath, field2.payload, lineNumber, asList, asBlockquote); } }); await this.plugin.app.vault.modify(this.file, this.renderNote()); } renderNote() { return this.lines.map((line) => line.rawContent).join("\n"); } static async buildNote(plugin, file) { const note = new Note(plugin, file); await note.build(); return note; } static async getExistingFields(plugin, file) { const note = await Note.buildNote(plugin, file); return note.existingFields; } static async getExistingFieldForIndexedPath(plugin, file, indexedPath) { const eFs = await Note.getExistingFields(plugin, file); return eFs.find((eF) => eF.indexedPath === indexedPath); } }; // src/commands/insertMissingFields.ts async function insertMissingFields(plugin, fileOrFilePath, lineNumber, asList = false, asBlockquote = false, fileClassName, indexedPath) { var _a; const file = getFileFromFileOrPath(plugin, fileOrFilePath); const note = await Note.buildNote(plugin, file); const f = plugin.fieldIndex; const fields = f.filesFields.get(file.path); const filteredClassFields = fileClassName ? ((_a = plugin.fieldIndex.fileClassesFields.get(fileClassName)) == null ? void 0 : _a.filter((field2) => field2.fileClassName === fileClassName)) || void 0 : void 0; const fieldsToInsert = []; if (!indexedPath) { fields == null ? void 0 : fields.filter((field2) => field2.isRoot() && !note.existingFields.map((_f) => _f.field.id).includes(field2.id)).filter((field2) => filteredClassFields ? filteredClassFields.map((f2) => f2.id).includes(field2.id) : true).reverse().forEach((field2) => { fieldsToInsert.push({ indexedPath: field2.id, payload: { value: "" } }); }); } else { const { id, index } = getIdAndIndex(indexedPath == null ? void 0 : indexedPath.split("____").last()); const existingFields = note.existingFields.filter((_f) => { var _a2; const upperIndexedIdsInPath = (_a2 = _f.indexedPath) == null ? void 0 : _a2.split("____"); upperIndexedIdsInPath == null ? void 0 : upperIndexedIdsInPath.pop(); return (upperIndexedIdsInPath == null ? void 0 : upperIndexedIdsInPath.join("____")) === indexedPath; }); const missingFields = (note == null ? void 0 : note.fields.filter((_f) => { var _a2; return ((_a2 = _f.getFirstAncestor()) == null ? void 0 : _a2.id) === id; }).filter((_f) => !existingFields.map((eF) => eF.field.id).includes(_f.id)).reverse()) || []; missingFields.forEach((field2) => { fieldsToInsert.push({ indexedPath: `${indexedPath}____${field2.id}`, payload: { value: "" } }); }); } if (fieldsToInsert.length) await postValues(plugin, fieldsToInsert, file, lineNumber, asList, asBlockquote); } // src/components/FieldsModal.ts var FieldActions = class { constructor(container) { this.container = container; } async setIconAndTooltipAsync(fieldOption, file, indexedPath, plugin) { const eF = await Note.getExistingFieldForIndexedPath(plugin, file, indexedPath); switch (eF == null ? void 0 : eF.field.type) { case "Boolean": { const value = stringToBoolean(eF == null ? void 0 : eF.value); fieldOption.setIcon(!value ? "toggle-left" : "toggle-right"); fieldOption.setTooltip(!value ? `Set ${eF.name} as true` : `Set ${eF.name} as false`); } break; default: { fieldOption.setIcon("pencil"); fieldOption.setTooltip(`Update ${(eF == null ? void 0 : eF.name) || ""}`); } } } addOption(id, icon, onclick, tooltip, className, file, indexedPath, plugin) { const fieldOptionContainer = this.container.createDiv({ cls: "field-item field-option" }); const fieldOption = new import_obsidian65.ButtonComponent(fieldOptionContainer); fieldOption.buttonEl.setAttr("id", id); if (indexedPath && file && plugin) { this.setIconAndTooltipAsync(fieldOption, file, indexedPath, plugin); } else { fieldOption.setIcon(icon); if (tooltip) fieldOption.setTooltip(tooltip); } if (className) fieldOption.buttonEl.addClass(className.replace(" ", "_")); fieldOption.onClick(() => onclick()); } }; var FieldOptions = class extends FieldActions { }; var FieldsModal = class extends import_obsidian65.Modal { constructor(plugin, file, noteFields, indexedPath) { super(plugin.app); this.plugin = plugin; this.file = file; this.noteFields = noteFields; this.indexedPath = indexedPath; this.existingFields = []; this.missingFields = []; this.containerEl.addClass("metadata-menu"); this.containerEl.addClass("note-fields-modal"); } async onOpen() { await this.buildNote(); this.build(); } async buildNote() { this.note = await Note.buildNote(this.plugin, this.file); } build() { var _a; this.contentEl.replaceChildren(); const indexedPath = this.indexedPath || ""; const { id, index } = getIdAndIndex(indexedPath == null ? void 0 : indexedPath.split("____").last()); if (!id) { this.titleEl.setText(`Fields of ${this.file.basename}`); } else { const baseTitle = `Fields of ${this.file.basename} ${(indexedPath == null ? void 0 : indexedPath.split("____").length) > 1 ? " > ... > " : " > "}`; if (index) { const objectListIndexedPath = upperIndexedPathObjectPath(this.indexedPath || ""); const eF = this.note.getExistingFieldForIndexedPath(objectListIndexedPath); const display = `${eF.name}[${index}]`; this.titleEl.setText(`${baseTitle} ${display}`); } else { const eF = this.note.getExistingFieldForIndexedPath(indexedPath); this.titleEl.setText(`${baseTitle} ${eF == null ? void 0 : eF.name}`); } } this.existingFields = this.note.existingFields.filter((_f) => { var _a2; if (!this.indexedPath) { return _f.isRoot(); } else { const upperIndexedIdsInPath = (_a2 = _f.indexedPath) == null ? void 0 : _a2.split("____"); upperIndexedIdsInPath == null ? void 0 : upperIndexedIdsInPath.pop(); return (upperIndexedIdsInPath == null ? void 0 : upperIndexedIdsInPath.join("____")) === this.indexedPath; } }); this.missingFields = ((_a = this.note) == null ? void 0 : _a.fields.filter((_f) => { var _a2; if (this.indexedPath) return ((_a2 = _f.getFirstAncestor()) == null ? void 0 : _a2.id) === id; else return _f.isRoot(); }).filter((_f) => !this.existingFields.map((eF) => eF.field.id).includes(_f.id))) || []; if (this.indexedPath) { this.buildNavigation(); this.contentEl.createEl("hr", { cls: "navigation-separator" }); } else { this.contentEl.createEl("hr"); } this.buildFieldsContainer(); this.contentEl.createEl("hr"); const fileClassManagersContainer = this.contentEl.createDiv({ cls: "fields-container" }); this.buildFileClassManager(fileClassManagersContainer); this.plugin.app.workspace.trigger("metadata-menu:fields-modal-built", this); } buildNavigation() { const backBtnWrapper = this.contentEl.createDiv({ cls: "back-button-wrapper" }); const backBtn = new import_obsidian65.ButtonComponent(backBtnWrapper); backBtn.setIcon("chevron-left"); const upperPath2 = upperIndexedPathObjectPath(this.indexedPath || ""); const { id: upperId, index: upperIndex } = getIdAndIndex(upperPath2.split("____").last()); const upperExistingField = this.note.existingFields.find((eF) => eF.field.id === upperId); const upperObject = upperExistingField == null ? void 0 : upperExistingField.field; if (upperObject) { const numIndex = parseInt(upperIndex || ""); if (!isNaN(numIndex)) { const display = `${upperObject.name} [${numIndex}]`; backBtnWrapper.createSpan({ text: display }); backBtn.setTooltip(`Go to ${display}`); } else { backBtnWrapper.createSpan({ text: upperObject.name }); backBtn.setTooltip(`Go to ${upperObject.name} fields`); } } else { const fileName = this.file.name.replace(/(.*).md$/, "$1"); backBtnWrapper.createSpan({ text: fileName }); backBtn.setTooltip(`Go to ${fileName} fields`); } backBtnWrapper.onclick = async () => { await this.noteFields.moveToObject(upperPath2); }; } buildFieldContainer(container, field2, value, indexedPath) { const eF = this.existingFields.find((eF2) => eF2.field.id === field2.id); const fieldVM = fieldValueManager(this.plugin, field2.id, field2.fileClassName, this.file, eF, indexedPath); const fieldNameWrapper = container.createDiv({ cls: "field-name-wrapper" }); const fieldNameContainer = fieldNameWrapper.createDiv({ text: `${field2.name}`, cls: "field-item field-name" }); this.buildFieldSetting(container, field2, fieldNameContainer); this.buildFieldValue(container, field2, fieldVM, value); this.buildActions(container, field2, fieldVM, value); } buildFieldSetting(container, field2, fieldNameContainer, isObjectListItem = false) { const fieldSettingsWrapper = container.createDiv({ cls: "field-settings-wrapper" }); fieldSettingsWrapper.createDiv({ cls: "field-settings-spacer" }); const fileClass = field2.fileClassName ? this.plugin.fieldIndex.fileClassesName.get(field2.fileClassName) : void 0; if (fileClass) { fieldNameContainer.addClass(`fileClassField__${fileClass.name.replace("/", "___").replaceAll(" ", "_")}`); } const fieldSettingContainer = fieldSettingsWrapper.createDiv({ cls: "field-item field-setting" }); const fieldSettingBtn = new import_obsidian65.ButtonComponent(fieldSettingContainer); fieldSettingBtn.setIcon("gear"); fieldSettingBtn.setTooltip(`${field2.fileClassName ? field2.fileClassName + " > " : "Preset Field > "} ${field2.name} settings`); fieldSettingBtn.onClick(() => { const _fileClass = field2.fileClassName ? this.plugin.fieldIndex.fileClassesName.get(field2.fileClassName) : void 0; const fileClassAttribute = _fileClass == null ? void 0 : _fileClass.attributes.find((attr) => attr.id === field2.id); if (fileClassAttribute && _fileClass) openSettings(fileClassAttribute.id, _fileClass.name, this.plugin); }); const fieldTypeContainer = fieldSettingsWrapper.createDiv({ cls: `field-item` }); fieldTypeContainer.createDiv({ text: `${field2.type}${isObjectListItem ? " item" : ""}`, cls: `chip field-type ${field2.colorClass}` }); } buildFieldValue(container, field2, fieldVM, value) { const fieldValueWrapper = container.createDiv({ cls: "field-value-wrapper" }); const fieldValueContainer = fieldValueWrapper.createDiv({ cls: ![void 0, null, ""].includes(value) ? "field-item field-value" : "field-item field-value emptyfield" }); if (value === null || value === "") { fieldValueContainer.setText(field2.type === "Lookup" ? "---auto---" : ""); } else if (value === void 0) { fieldValueContainer.setText(""); } else { if (fieldVM) displayValue27(field2.type)(fieldVM, fieldValueContainer, () => { this.close(); }); else fieldValueContainer.setText(`${value}`); } } buildActions(container, field2, fieldVM, value) { const fieldOptionsWrapper = container.createDiv({ cls: "field-options-wrapper" }); fieldOptionsWrapper.createDiv({ cls: "field-options-spacer" }); const fieldOptions = new FieldOptions(fieldOptionsWrapper); if (this.existingFields.map((_f) => _f.field.id).includes(field2.id) && fieldVM) { if (objectTypes.includes(field2.type)) { getActions(field2.type)(this.plugin, field2, this.file, fieldOptions, fieldVM.indexedPath, this.noteFields); } else { getActions(field2.type)(this.plugin, field2, this.file, fieldOptions, fieldVM.indexedPath); } } else { const newIndexedPath = `${this.indexedPath ? this.indexedPath + "____" : ""}${field2.id}`; const fieldBtnContainer = fieldOptionsWrapper.createDiv({ cls: "field-item field-option" }); const fieldBtn = new import_obsidian65.ButtonComponent(fieldBtnContainer); fieldBtn.setIcon("list-plus"); fieldBtn.setTooltip("Add field at section"); fieldBtn.onClick(async () => { var _a; if (objectTypes.includes(field2.type) && this.note) { await postValues(this.plugin, [{ indexedPath: `${newIndexedPath}`, payload: { value: "" } }], this.file); this.indexedPath = `${newIndexedPath}`; } else { if (field2.path === "") { new chooseSectionModal( this.plugin, this.file, (lineNumber, asList, asBlockquote) => { var _a2; return (_a2 = fieldValueManager(this.plugin, field2.id, field2.fileClassName, this.file, void 0, newIndexedPath, lineNumber, asList, asBlockquote)) == null ? void 0 : _a2.openModal(); } ).open(); } else { (_a = fieldValueManager(this.plugin, field2.id, field2.fileClassName, this.file, void 0, newIndexedPath, -1, false, false)) == null ? void 0 : _a.openModal(); } } }); } ; } buildObjectListItemContainer(container, field2, itemIndexedPath) { const fieldVM = fieldValueManager(this.plugin, field2.id, field2.fileClassName, this.file); const { index } = getIdAndIndex(itemIndexedPath.split("____").last()); let value = ""; if (this.indexedPath && index) { const eF = this.note.getExistingFieldForIndexedPath(this.indexedPath); value = (eF == null ? void 0 : eF.getItemDisplayForIndex(this.plugin, index)) || ""; } const fieldNameWrapper = container.createDiv({ cls: "field-name-wrapper" }); const fieldNameContainer = fieldNameWrapper.createDiv({ text: `${field2.name} [${index}]`, cls: "field-item field-name" }); this.buildFieldSetting(container, field2, fieldNameContainer, true); const fieldValueWrapper = container.createDiv({ cls: "field-value-wrapper" }); const fieldValueContainer = fieldValueWrapper.createDiv({ cls: value !== void 0 && value !== null ? "field-item field-value" : "field-item field-value emptyfield" }); fieldValueContainer.setText(value); const fieldOptionsWrapper = container.createDiv({ cls: "field-options-wrapper" }); fieldOptionsWrapper.createDiv({ cls: "field-options-spacer" }); const fieldOptions = new FieldOptions(fieldOptionsWrapper); if (fieldVM) getActions(fieldVM == null ? void 0 : fieldVM.type)(this.plugin, field2, this.file, fieldOptions, itemIndexedPath, this.noteFields); } buildFileClassManager(container) { const fileClasses = this.plugin.fieldIndex.filesFileClasses.get(this.file.path) || []; fileClasses.forEach((fileClass) => { const fileClassManagerContainer = container.createDiv({ cls: "fields-inheritance-manager-container" }); const _ancestors = this.plugin.fieldIndex.fileClassesAncestors.get(fileClass.name) || []; const ancestors = [..._ancestors].reverse(); ancestors.push(fileClass.name); ancestors.forEach(async (fileClassName, i) => { const _fileClass = this.plugin.fieldIndex.fileClassesName.get(fileClassName); if (_fileClass) { const fileClassOptionsContainer = fileClassManagerContainer.createDiv({ cls: "fileclass-manager-container" }); const fileClassNameContainer = fileClassOptionsContainer.createDiv({ cls: "name", text: _fileClass.name }); fileClassNameContainer.setAttr("id", `fileClass__${_fileClass.name.replace("/", "___").replace(" ", "_")}`); if (await _fileClass.missingFieldsForFileClass(this.file)) { const fileClassInsertMissingFieldsInFrontmatterBtn = new import_obsidian65.ButtonComponent(fileClassOptionsContainer); fileClassInsertMissingFieldsInFrontmatterBtn.setIcon("align-vertical-space-around"); fileClassInsertMissingFieldsInFrontmatterBtn.setTooltip(`Insert missing fields for ${_fileClass.name}`); fileClassInsertMissingFieldsInFrontmatterBtn.onClick(() => { insertMissingFields(this.plugin, this.file.path, -1, false, false, _fileClass.name); }); const fileClassInsertMissingFieldsBtn = new import_obsidian65.ButtonComponent(fileClassOptionsContainer); fileClassInsertMissingFieldsBtn.setIcon("log-in"); fileClassInsertMissingFieldsBtn.setTooltip(`Insert missing fields for ${_fileClass.name}`); fileClassInsertMissingFieldsBtn.onClick(() => { new chooseSectionModal( this.plugin, this.file, (lineNumber, asList, asBlockquote) => insertMissingFields( this.plugin, this.file.path, lineNumber, asList, asBlockquote, _fileClass.name ) ).open(); }); } const fileClassAddAttributeBtn = new import_obsidian65.ButtonComponent(fileClassOptionsContainer); fileClassAddAttributeBtn.setIcon("plus-circle"); fileClassAddAttributeBtn.setTooltip(`Add field definition in ${_fileClass.name}`); fileClassAddAttributeBtn.onClick(() => openSettings("", fileClassName, this.plugin)); if (i < ancestors.length - 1) { fileClassOptionsContainer.createDiv({ text: ">", cls: "separator" }); } const fileClassFieldsContainers = this.containerEl.querySelectorAll(`[class*="fileClassField__${fileClassName.replace("/", "___").replace(" ", "_")}"]`); fileClassFieldsContainers.forEach((fieldNameContainer) => { fieldNameContainer.onmouseover = () => { fileClassNameContainer == null ? void 0 : fileClassNameContainer.addClass("active"); }; fieldNameContainer.onmouseout = () => { fileClassNameContainer == null ? void 0 : fileClassNameContainer.removeClass("active"); }; }); fileClassNameContainer.onmouseover = () => { this.containerEl.querySelectorAll(`.field-item.field-name.fileClassField__${fileClassName.replace("/", "___").replace(" ", "_")}`).forEach((cont) => { cont.addClass("active"); }); }; fileClassNameContainer.onmouseout = () => { this.containerEl.querySelectorAll(`.field-item.field-name.fileClassField__${fileClassName.replace("/", "___").replace(" ", "_")}`).forEach((cont) => { cont.removeClass("active"); }); }; fileClassNameContainer.onclick = () => { const fileClassComponent = new FileClassViewManager(this.plugin, _fileClass); this.plugin.addChild(fileClassComponent); fileClassComponent.build(); this.close(); }; } }); }); } buildInsertMissingFieldsBtn() { const insertMissingFieldsContainer = this.contentEl.createDiv({ cls: "insert-all-fields" }); insertMissingFieldsContainer.createDiv({ text: "Insert missing fields" }); const insertMissingFieldsInFrontmatterBtn = new import_obsidian65.ButtonComponent(insertMissingFieldsContainer); insertMissingFieldsInFrontmatterBtn.setIcon("align-vertical-space-around"); insertMissingFieldsInFrontmatterBtn.setTooltip("In Frontmatter"); insertMissingFieldsInFrontmatterBtn.buttonEl.addClass("in-frontmatter-btn"); insertMissingFieldsInFrontmatterBtn.onClick(() => { var _a; if (!this.indexedPath) { insertMissingFields(this.plugin, this.file.path, -1); } else { const field2 = (_a = this.note.getExistingFieldForIndexedPath(this.indexedPath)) == null ? void 0 : _a.field; const fileClass = (field2 == null ? void 0 : field2.fileClassName) ? this.plugin.fieldIndex.fileClassesName.get(field2.fileClassName) : void 0; insertMissingFields(this.plugin, this.file.path, -1, false, false, fileClass == null ? void 0 : fileClass.name, this.indexedPath); } }); const insertMissingFieldsBtn = new import_obsidian65.ButtonComponent(insertMissingFieldsContainer); insertMissingFieldsBtn.setIcon("log-in"); insertMissingFieldsBtn.setTooltip("At line..."); insertMissingFieldsBtn.buttonEl.addClass("at-line-btn"); insertMissingFieldsBtn.onClick(() => { var _a; if (!this.indexedPath) { new chooseSectionModal( this.plugin, this.file, (lineNumber, asList, asBlockquote) => insertMissingFields( this.plugin, this.file.path, lineNumber, asList, asBlockquote ) ).open(); } else { const field2 = (_a = this.note.getExistingFieldForIndexedPath(this.indexedPath)) == null ? void 0 : _a.field; const fileClass = (field2 == null ? void 0 : field2.fileClassName) ? this.plugin.fieldIndex.fileClassesName.get(field2.fileClassName) : void 0; insertMissingFields( this.plugin, this.file.path, -1, false, false, fileClass == null ? void 0 : fileClass.name, this.indexedPath ); } }); } buildInsertNewItem(field2, indexedPath) { const insertNewItemContainer = this.contentEl.createDiv({ cls: "insert-all-fields" }); insertNewItemContainer.createDiv({ text: "Add a new item" }); const insertNewItemBtn = new import_obsidian65.ButtonComponent(insertNewItemContainer); insertNewItemBtn.setIcon("list-plus"); insertNewItemBtn.onClick(async () => { if (this.note) { const fieldVM = fieldValueManager(this.plugin, field2.id, field2.fileClassName, this.file, void 0, this.indexedPath); addObjectListItem(fieldVM); } this.indexedPath = indexedPath; }); } buildFieldsContainer() { var _a, _b, _c; const fieldsContainer = this.contentEl.createDiv({ cls: "note-fields-container" }); const { id, index } = getIdAndIndex((_a = this.indexedPath) == null ? void 0 : _a.split("____").last()); if (this.indexedPath && ((_b = this.note.fields.find((_f) => _f.id === id)) == null ? void 0 : _b.type) === "ObjectList" && index === void 0) { const field2 = this.note.fields.find((_f) => _f.id === id); const items = ((_c = this.note.existingFields.find((eF) => eF.indexedPath === this.indexedPath)) == null ? void 0 : _c.value) || []; items.forEach((item, index2) => this.buildObjectListItemContainer(fieldsContainer, field2, `${this.indexedPath}[${index2}]`)); this.buildInsertNewItem(field2, this.indexedPath); } else { const sortedIds = sortFileFields(this.plugin.fieldIndex, this.file).map((f) => f.id); const fields = [ ...this.existingFields.filter((eF) => { if (eF.name === this.plugin.settings.fileClassAlias) return this.plugin.settings.showFileClassSelectInModal; else return true; }), ...this.missingFields.sort((f1, f2) => sortedIds.indexOf(f1.id) < sortedIds.indexOf(f2.id) ? -1 : 1) ]; for (const fieldOrEf of fields) { if (fieldOrEf instanceof ExistingField2) { this.buildFieldContainer(fieldsContainer, fieldOrEf.field, fieldOrEf.value, fieldOrEf.indexedPath); } else { this.buildFieldContainer(fieldsContainer, fieldOrEf, void 0); } } if (this.missingFields.length) this.buildInsertMissingFieldsBtn(); } } }; var NoteFieldsComponent = class extends import_obsidian65.Component { constructor(plugin, cacheVersion, onChange, file, indexedPath) { super(); this.plugin = plugin; this.cacheVersion = cacheVersion; this.onChange = onChange; this.file = file; this.indexedPath = indexedPath; this.fieldsModal = new FieldsModal(this.plugin, this.file, this, this.indexedPath); this.fieldsModal.onClose = () => { this.plugin.removeChild(this); this.unload(); }; } async moveToObject(indexedPath) { await this.fieldsModal.buildNote(); this.fieldsModal.indexedPath = indexedPath; this.fieldsModal.build(); } onload() { this.registerEvent( this.plugin.app.metadataCache.on("metadata-menu:indexed", async () => { await this.fieldsModal.buildNote(); this.fieldsModal.build(); }) ); this.fieldsModal.open(); } }; // src/commands/paletteCommands.ts function fileClassAttributeOptionsCommand(plugin) { const classFilesPath = plugin.settings.classFilesPath; plugin.addCommand({ id: "fileClassAttr_options", name: "All fileClass attributes options", icon: "gear", checkCallback: (checking) => { const view = plugin.app.workspace.getActiveViewOfType(import_obsidian66.MarkdownView); const inFileClass = !!(classFilesPath && !!(view == null ? void 0 : view.file) && view.file.path.startsWith(classFilesPath)); if (checking) { return inFileClass; } if (inFileClass) { const fieldCommandSuggestModal = new FieldCommandSuggestModal(plugin.app); const fileClassOptionsList = new FileClassOptionsList(plugin, view.file, fieldCommandSuggestModal); fileClassOptionsList.createExtraOptionList(); } } }); } function insertFileClassAttributeCommand(plugin) { const classFilesPath = plugin.settings.classFilesPath; plugin.addCommand({ id: "insert_fileClassAttr", name: "Insert a new fileClass attribute", icon: "list-plus", checkCallback: (checking) => { const view = plugin.app.workspace.getActiveViewOfType(import_obsidian66.MarkdownView); const inFileClass = !!(classFilesPath && !!(view == null ? void 0 : view.file) && view.file.path.startsWith(classFilesPath)); if (checking) { return inFileClass; } if (inFileClass) { try { const fileClassName = getFileClassNameFromPath(plugin.settings, view.file.path); if (fileClassName) openSettings("", fileClassName, plugin); } catch (error) { new import_obsidian66.Notice("plugin is not a valid fileClass"); } } } }); } function insertFieldAtPositionCommand(plugin) { const classFilesPath = plugin.settings.classFilesPath; plugin.addCommand({ id: "insert_field_at_cursor", name: "Choose a field to insert at cursor", icon: "list-plus", checkCallback: (checking) => { const view = plugin.app.workspace.getActiveViewOfType(import_obsidian66.MarkdownView); const inFile = !!((view == null ? void 0 : view.file) && (!classFilesPath || !view.file.path.startsWith(classFilesPath))); if (checking) { return inFile; } if (inFile) { const optionsList = new OptionsList(plugin, view.file, "InsertFieldCommand"); (async () => await optionsList.createExtraOptionList())(); } } }); } function fieldOptionsCommand(plugin) { const classFilesPath = plugin.settings.classFilesPath; plugin.addCommand({ id: "field_options", name: "Fields options", icon: "gear", checkCallback: (checking) => { const view = plugin.app.workspace.getActiveViewOfType(import_obsidian66.MarkdownView); const inFile = !!((view == null ? void 0 : view.file) && (!classFilesPath || !view.file.path.startsWith(classFilesPath))); if (checking) { return inFile; } if (inFile) { const fieldCommandSuggestModal = new FieldCommandSuggestModal(plugin.app); const optionsList = new OptionsList(plugin, view.file, fieldCommandSuggestModal); (async () => await optionsList.createExtraOptionList())(); } } }); } function manageFieldAtCursorCommand(plugin) { const classFilesPath = plugin.settings.classFilesPath; plugin.addCommand({ id: "field_at_cursor_options", name: "Manage field at cursor", icon: "text-cursor-input", checkCallback: (checking) => { const view = plugin.app.workspace.getActiveViewOfType(import_obsidian66.MarkdownView); const editor = view == null ? void 0 : view.editor; const inFile = !!((view == null ? void 0 : view.file) && (!classFilesPath || !view.file.path.startsWith(classFilesPath))); if (checking) { return inFile && editor !== void 0; } if (inFile && editor !== void 0) { const optionsList = new OptionsList(plugin, view.file, "ManageAtCursorCommand"); (async function() { var _a; const note = await Note.buildNote(plugin, view.file); switch (view.getMode()) { case "source": { const node = note.getNodeAtPosition(editor.getCursor()); if (node) optionsList.createAndOpenNodeFieldModal(node); else new import_obsidian66.Notice("No field with definition at this position", 2e3); } break; case "preview": { const focusedElement = document.querySelector(".metadata-property:focus-within"); if (focusedElement instanceof HTMLElement) { const key = focusedElement.dataset.propertyKey; const field2 = key && ((_a = plugin.fieldIndex.filesFields.get(view.file.path)) == null ? void 0 : _a.find((_f) => _f.isRoot() && _f.name === key)); if (field2) { const node = note.getNodeForIndexedPath(field2.id); if (node) optionsList.createAndOpenNodeFieldModal(node); else new import_obsidian66.Notice("No field with definition at this position", 2e3); } else if (key === plugin.settings.fileClassAlias) { const node = note.getNodeForIndexedPath(`fileclass-field-${plugin.settings.fileClassAlias}`); if (node) optionsList.createAndOpenNodeFieldModal(node); else new import_obsidian66.Notice("No field with definition at this position", 2e3); } } break; } } })(); } } }); } function insertMissingFieldsCommand(plugin) { const classFilesPath = plugin.settings.classFilesPath; plugin.addCommand({ id: "insert_missing_fields", name: "Bulk insert missing fields", icon: "battery-full", checkCallback: (checking) => { const view = plugin.app.workspace.getActiveViewOfType(import_obsidian66.MarkdownView); const inFile = !!((view == null ? void 0 : view.file) && (!classFilesPath || !view.file.path.startsWith(classFilesPath))); if (checking) { return inFile; } if (inFile) { (async function() { const file = view.file; const existingFields = await Note.getExistingFields(plugin, file); const existingFieldsNames = existingFields.map((eF) => eF.field.name); if (![...plugin.fieldIndex.filesFields.get(file.path) || []].map((field2) => field2.name).every((fieldName) => existingFieldsNames.includes(fieldName))) { new chooseSectionModal( plugin, file, (lineNumber, asList, asBlockquote) => insertMissingFields( plugin, file.path, lineNumber, asList, asBlockquote ) ).open(); } })(); } } }); } function openFieldsModalCommand(plugin) { const classFilesPath = plugin.settings.classFilesPath; plugin.addCommand({ id: "open_fields_modal", name: "Open this note's fields modal", icon: "clipboard-list", checkCallback: (checking) => { const view = plugin.app.workspace.getActiveViewOfType(import_obsidian66.MarkdownView); const inFile = !!((view == null ? void 0 : view.file) && (!classFilesPath || !view.file.path.startsWith(classFilesPath))); if (checking) { return inFile; } if (inFile) { const file = view.file; if (inFile && file instanceof import_obsidian66.TFile && file.extension === "md") { const noteFieldsComponent = new NoteFieldsComponent(plugin, "1", () => { }, file); plugin.addChild(noteFieldsComponent); } } } }); } function insertFieldCommand(plugin, command, field2, fileClassName) { plugin.addCommand({ id: command.id, name: command.label, icon: command.icon, checkCallback: (checking) => { const view = plugin.app.workspace.getActiveViewOfType(import_obsidian66.MarkdownView); const fR = command.id.match(/insert__(?.*)/); const fileClasses = (view == null ? void 0 : view.file) ? plugin.fieldIndex.filesFileClasses.get(view == null ? void 0 : view.file.path) : void 0; const belongsToView = field2 !== void 0 && !!(view == null ? void 0 : view.file) && (!!fileClasses && fileClasses.some((fileClass) => fileClass.name === fileClassName) || !fileClasses && !fileClassName); if (checking) return belongsToView; if ((view == null ? void 0 : view.file) && field2) { new chooseSectionModal( plugin, view.file, (lineNumber, asList, asBlockquote) => { var _a; (_a = fieldValueManager(plugin, field2.id, field2.fileClassName, view.file, void 0, void 0, lineNumber, asList, asBlockquote)) == null ? void 0 : _a.openModal(); } ).open(); } } }); } function insertIFieldCommand(plugin, command, field2, fileClassName) { plugin.addCommand({ id: command.id, name: command.label, icon: command.icon, checkCallback: (checking) => { const view = plugin.app.workspace.getActiveViewOfType(import_obsidian66.MarkdownView); const fR = command.id.match(/insert__(?.*)/); const fileClasses = (view == null ? void 0 : view.file) ? plugin.fieldIndex.filesFileClasses.get(view == null ? void 0 : view.file.path) : void 0; const belongsToView = field2 !== void 0 && !!(view == null ? void 0 : view.file) && (!!fileClasses && fileClasses.some((fileClass) => fileClass.name === fileClassName) || !fileClasses && !fileClassName); if (checking) return belongsToView; if ((view == null ? void 0 : view.file) && field2) { new chooseSectionModal( plugin, view.file, (lineNumber, asList, asBlockquote) => { fieldValueManager(plugin, field2.id, field2.fileClassName, view.file, void 0, void 0, lineNumber, asList, asBlockquote); } ).open(); } } }); } function insertFieldsCommand(plugin) { const fields = []; plugin.presetFields.forEach((f) => { if (f.command && f.isRoot()) fields.push({ field: f, fileClassName: void 0 }); }); [...plugin.fieldIndex.fileClassesFields].forEach(([fileClassName, _fields]) => { _fields.forEach((field2) => { if (field2.command && field2.isRoot()) { fields.push({ field: field2, fileClassName }); } }); }); fields.forEach((_field) => { if (_field.field.command) { const { field: field2, fileClassName } = _field; const command = field2.command; insertFieldCommand(plugin, command, field2, fileClassName); } }); } function openFileclassViewCommand(plugin) { plugin.addCommand({ id: "open_fileclass_view", name: "Open fileClass view", icon: "package", checkCallback: (checking) => { var _a; if (checking) { return true; } const activeFilePath = (_a = plugin.app.workspace.getActiveFile()) == null ? void 0 : _a.path; const fileClass = activeFilePath ? plugin.fieldIndex.fileClassesPath.get(activeFilePath) : void 0; const fileClassComponent = new FileClassViewManager(plugin, fileClass); plugin.addChild(fileClassComponent); fileClassComponent.build(); } }); } function fileclassToFileCommand(plugin) { plugin.addCommand({ id: "add_fileclass_to_file", name: "Add fileClass to file", icon: "package-plus", checkCallback: (checking) => { const activeFile = plugin.app.workspace.getActiveFile(); if (checking) { return !!activeFile; } if (activeFile) { const modal = new AddFileClassToFileModal(plugin, activeFile); modal.open(); } } }); } function updateLookupsAndFormulasCommand(plugin) { plugin.addCommand({ id: "update_all_lookups", name: "Update all lookups and formulas", icon: "file-search", checkCallback: (checking) => { if (checking) return true; plugin.fieldIndex.fullIndex(true); } }); } function updateFileLookupsCommand(plugin) { const classFilesPath = plugin.settings.classFilesPath; plugin.addCommand({ id: "update_file_lookups", name: "Update active file lookups fields", icon: "file-search", checkCallback: (checking) => { var _a; const view = plugin.app.workspace.getActiveViewOfType(import_obsidian66.MarkdownView); const inFile = !!((view == null ? void 0 : view.file) && (!classFilesPath || !view.file.path.startsWith(classFilesPath))); if (checking) { return inFile; } if (inFile) { const file = view.file; if (inFile && file instanceof import_obsidian66.TFile && file.extension === "md") { const lookupFields = (_a = plugin.fieldIndex.filesFields.get(file.path)) == null ? void 0 : _a.filter((field2) => field2.type === "Lookup"); lookupFields == null ? void 0 : lookupFields.forEach(async (field2) => { await updateLookups(plugin, { file, fieldName: field2.name }); await plugin.fieldIndex.applyUpdates(); }); } } } }); } function updateFileFormulasCommand(plugin) { const classFilesPath = plugin.settings.classFilesPath; plugin.addCommand({ id: "update_file_formulas", name: "Update active file formulas fields", icon: "function-square", checkCallback: (checking) => { var _a; const view = plugin.app.workspace.getActiveViewOfType(import_obsidian66.MarkdownView); const inFile = !!((view == null ? void 0 : view.file) && (!classFilesPath || !view.file.path.startsWith(classFilesPath))); if (checking) { return inFile; } if (inFile) { const file = view.file; if (inFile && file instanceof import_obsidian66.TFile && file.extension === "md") { const formulaFields = (_a = plugin.fieldIndex.filesFields.get(file.path)) == null ? void 0 : _a.filter((field2) => field2.type === "Formula"); formulaFields == null ? void 0 : formulaFields.forEach(async (field2) => { await updateFormulas(plugin, { file, fieldName: field2.name }); await plugin.fieldIndex.applyUpdates(); }); } } } }); } function addCommands(plugin) { fileClassAttributeOptionsCommand(plugin); insertFileClassAttributeCommand(plugin); fieldOptionsCommand(plugin); insertFieldAtPositionCommand(plugin); manageFieldAtCursorCommand(plugin); insertMissingFieldsCommand(plugin); openFieldsModalCommand(plugin); insertFieldsCommand(plugin); updateFileLookupsCommand(plugin); updateFileFormulasCommand(plugin); openFileclassViewCommand(plugin); fileclassToFileCommand(plugin); updateLookupsAndFormulasCommand(plugin); } // src/components/ContextMenu.ts var import_obsidian67 = require("obsidian"); var ContextMenu = class extends import_obsidian67.Component { constructor(plugin) { super(); this.plugin = plugin; this.fileContextMenuOpened = false; } onload() { this.plugin.registerEvent( this.plugin.app.workspace.on("file-menu", async (menu, abstractFile, source) => { this.fileContextMenuOpened = true; const file = this.plugin.app.vault.getAbstractFileByPath(abstractFile.path); this.buildOptions(file, menu); menu.onHide = () => { this.fileContextMenuOpened = false; }; }) ); this.plugin.registerEvent( this.plugin.app.workspace.on("editor-menu", (menu, editor, view) => { if (!this.fileContextMenuOpened) { const file = this.plugin.app.workspace.getActiveFile(); this.buildOptions(file, menu); } }) ); } buildOptions(file, menu) { const classFilesPath = this.plugin.settings.classFilesPath; if (file instanceof import_obsidian67.TFile && file.extension === "md") { if (!import_obsidian67.Platform.isMobile && (0, import_obsidian67.requireApiVersion)("0.16.0")) { if (classFilesPath && file.path.startsWith(classFilesPath)) { const fileClassName = getFileClassNameFromPath(this.plugin.settings, file.path); menu.setSectionSubmenu( `metadata-menu-fileclass.${fileClassName}.fileclass-fields`, { title: "Manage fields", icon: "wrench" } ); } else { const fileClasses = this.plugin.fieldIndex.filesFileClasses.get(file.path) || []; fileClasses.forEach((fileClass) => { menu.setSectionSubmenu( `metadata-menu-fileclass.${fileClass.name}.fileclass-fields`, { title: `Manage ${fileClass.name} fields`, icon: "wrench" } ); }); } } if (this.plugin.settings.displayFieldsInContextMenu) { if (classFilesPath && file.path.startsWith(classFilesPath)) { const fileClassOptionsList = new FileClassOptionsList(this.plugin, file, menu); fileClassOptionsList.createExtraOptionList(); } else { const optionsList = new OptionsList(this.plugin, file, menu); optionsList.createContextMenuOptionsList(); } ; } else { menu.addItem((item) => { item.setIcon("list"); item.setTitle("Field Options"); item.onClick(async () => { const fieldCommandSuggestModal = new FieldCommandSuggestModal(this.plugin.app); const optionsList = new OptionsList(this.plugin, file, fieldCommandSuggestModal); await optionsList.createExtraOptionList(); }); }); } } ; } }; // src/components/ExtraButton.ts var import_obsidian70 = require("obsidian"); // src/options/linkAttributes.ts var import_obsidian68 = require("obsidian"); function clearExtraAttributes(link) { Object.values(link.attributes).forEach((attr) => { if (attr.name.includes("fileclass-name")) { link.removeAttribute(attr.name); const el = link.nextElementSibling; if (el == null ? void 0 : el.hasClass("fileclass-icon")) { el.remove(); } } }); } function setLinkMetadataFormButton(plugin, link, destPath, viewTypeName, fileClassName) { var _a, _b; const setStatus = (el) => { const path = destPath + ".md"; el.removeClass("field-status-changed"); el.removeClass("field-status-error"); el.removeClass("field-status-may-have-changed"); const changed = plugin.fieldIndex.dvQFieldChanged(path); const error = plugin.fieldIndex.dvQFieldHasAnError(path); const mayHaveChanged = plugin.fieldIndex.dvQFieldMayHaveChanged(path); if (error) el.addClass("field-status-error"); else if (changed) el.addClass("field-status-changed"); else if (mayHaveChanged) el.addClass("field-status-may-have-changed"); }; if (link.classList.contains("metadata-menu-button-hidden")) return; switch (viewTypeName) { case "a.internal-link": if (!plugin.settings.enableLinks) return; break; case "properties": if (!plugin.settings.enableLinks) return; break; case "tabHeader": if (!plugin.settings.enableTabHeader) return; break; case "starred": if (!plugin.settings.enableStarred) return; break; case "bookmarks": if (!plugin.settings.enableStarred) return; break; case "file-explorer": if (!plugin.settings.enableFileExplorer) return; break; case "backlink": if (!plugin.settings.enableBacklinks) return; break; case "search": if (!plugin.settings.enableSearch) return; break; case "outgoing-link": if (!plugin.settings.enableBacklinks) return; break; default: return; } for (const a of link.attributes) { if (a.name.includes("fileclass-name") && a.name !== fileClassName) { link.removeAttribute(a.name); const el = link.nextElementSibling; if (el == null ? void 0 : el.hasClass("fileclass-icon")) { el.remove(); } } } if (!plugin.fieldIndex.indexableFiles().map((f) => f.path).includes(`${destPath}.md`) && !plugin.fieldIndex.indexableFileClasses().map((f) => f.path).includes(`${destPath}.md`)) return; const classFilessPath = plugin.settings.classFilesPath; const fileClass = plugin.fieldIndex.fileClassesPath.get(destPath + ".md"); if (classFilessPath && fileClass) { const icon = fileClass.getIcon(); link.setAttribute("fileclass-name", fileClass.name); const el = link.nextElementSibling; if (!(el == null ? void 0 : el.hasClass("fileclass-icon"))) { const metadataMenuBtn = plugin.app.workspace.containerEl.createEl("a", { cls: "metadata-menu fileclass-icon" }); setStatus(metadataMenuBtn); if (metadataMenuBtn) { (0, import_obsidian68.setIcon)(metadataMenuBtn, icon); (_a = link.parentElement) == null ? void 0 : _a.insertBefore(metadataMenuBtn, link.nextSibling); metadataMenuBtn.onclick = (event) => { const fileClassViewManager = new FileClassViewManager(plugin, fileClass); plugin.addChild(fileClassViewManager); fileClassViewManager.build(); event.stopPropagation(); }; } } else { setStatus(el); } } else if (fileClassName) { const fileClass2 = plugin.fieldIndex.fileClassesName.get(fileClassName); if (fileClass2) { const icon = fileClass2.getIcon(); link.setAttribute("fileclass-name", fileClassName); const el = link.nextElementSibling; if (!(el == null ? void 0 : el.hasClass("fileclass-icon"))) { const metadataMenuBtn = plugin.app.workspace.containerEl.createEl("a", { cls: "metadata-menu fileclass-icon" }); setStatus(metadataMenuBtn); if (metadataMenuBtn) { (0, import_obsidian68.setIcon)(metadataMenuBtn, icon || plugin.settings.fileClassIcon); (_b = link.parentElement) == null ? void 0 : _b.insertBefore(metadataMenuBtn, link.nextSibling); if (viewTypeName === "a.internal-link" && metadataMenuBtn.closest(".fv-table")) metadataMenuBtn.addClass("dataview-fileclass-icon"); metadataMenuBtn.onclick = (event) => { const file = plugin.app.vault.getAbstractFileByPath(`${destPath}.md`); if (file instanceof import_obsidian68.TFile && file.extension === "md") { const noteFieldsComponent = new NoteFieldsComponent(plugin, "1", () => { }, file); plugin.addChild(noteFieldsComponent); } event.stopPropagation(); }; } } else { setStatus(el); } } } plugin.app.workspace.trigger("metadata-menu:button-built", destPath, viewTypeName, fileClassName); } function updateLinkMetadataMenuFormButton(app2, plugin, link, viewTypeName, source) { var _a, _b; const linkHref = (_a = link.getAttribute("href")) == null ? void 0 : _a.split("#")[0]; const dest = linkHref && app2.metadataCache.getFirstLinkpathDest(linkHref, source); if (dest) { const fileClassName = (_b = plugin.fieldIndex.filesFileClassesNames.get(dest.path)) == null ? void 0 : _b.last(); setLinkMetadataFormButton(plugin, link, dest.path.replace(/(.*).md/, "$1"), viewTypeName, fileClassName); } } function updateDivExtraAttributes(app2, plugin, link, viewTypeName, sourceName, _linkName) { var _a, _b, _c, _d, _e; switch (viewTypeName) { case "file-explorer": { const dataPath = (_a = link == null ? void 0 : link.parentElement) == null ? void 0 : _a.dataset.path; if (dataPath) { const fileClassName = (_b = plugin.fieldIndex.filesFileClassesNames.get(dataPath)) == null ? void 0 : _b.last(); setLinkMetadataFormButton(plugin, link, dataPath.replace(/(.*).md/, "$1"), viewTypeName, fileClassName); } } break; case "tabHeader": { if (sourceName) { const fileClassName = (_c = plugin.fieldIndex.filesFileClassesNames.get(sourceName)) == null ? void 0 : _c.last(); setLinkMetadataFormButton(plugin, link, sourceName.replace(/(.*).md/, "$1"), viewTypeName, fileClassName); } } break; case "outgoing-link": { const dest = link.innerText.split("\n")[0]; if (dest) { const fileClassName = (_d = plugin.fieldIndex.filesFileClassesNames.get(`${dest}.md`)) == null ? void 0 : _d.last(); setLinkMetadataFormButton(plugin, link, dest, viewTypeName, fileClassName); } } break; default: { const linkName = _linkName || link.textContent; const dest = linkName && app2.metadataCache.getFirstLinkpathDest((0, import_obsidian68.getLinkpath)(linkName), sourceName); if (dest) { const fileClassName = (_e = plugin.fieldIndex.filesFileClassesNames.get(dest.path)) == null ? void 0 : _e.last(); setLinkMetadataFormButton(plugin, link, dest.path.replace(/(.*).md/, "$1"), viewTypeName, fileClassName); } } break; } } function updateElLinks(app2, plugin, el, ctx) { const links = el.querySelectorAll("a.internal-link"); const source = ctx.sourcePath.replace(/(.*).md/, "$1"); links.forEach((link) => { updateLinkMetadataMenuFormButton(app2, plugin, link, "a.internal-link", source); }); } function updatePropertiesPane(propertiesEl, file, app2, plugin) { var _a, _b, _c, _d, _e, _f, _g, _h; const frontmatter = (_a = app2.metadataCache.getCache(file.path)) == null ? void 0 : _a.frontmatter; if (!!frontmatter) { const nodes = propertiesEl.querySelectorAll("div.internal-link > .multi-select-pill-content"); for (let i = 0; i < nodes.length; ++i) { const el = nodes[i]; const linkText = el.textContent; const keyEl = (_e = (_d = (_c = (_b = el == null ? void 0 : el.parentElement) == null ? void 0 : _b.parentElement) == null ? void 0 : _c.parentElement) == null ? void 0 : _d.parentElement) == null ? void 0 : _e.children[0].children[1]; const key = keyEl.value; const listOfLinks = frontmatter[key]; let foundS = null; if (!listOfLinks) { continue; } for (const s of listOfLinks) { if (s.length > 4 && s.startsWith("[[") && s.endsWith("]]")) { const slicedS = s.slice(2, -2); const split = slicedS.split("|"); if (split.length == 1 && split[0] == linkText) { foundS = split[0]; break; } else if (split.length == 2 && split[1] == linkText) { foundS = split[0]; break; } } } if (!!foundS) { updateDivExtraAttributes(plugin.app, plugin, el, "properties", foundS); } } const singleNodes = propertiesEl.querySelectorAll("div.metadata-link-inner"); for (let i = 0; i < singleNodes.length; ++i) { const el = singleNodes[i]; const linkText = el.textContent; const keyEl = (_h = (_g = (_f = el == null ? void 0 : el.parentElement) == null ? void 0 : _f.parentElement) == null ? void 0 : _g.parentElement) == null ? void 0 : _h.children[0].children[1]; const key = keyEl.value; const link = frontmatter[key]; if (!link) { continue; } let foundS = null; if (link.length > 4 && link.startsWith("[[") && link.endsWith("]]")) { const slicedS = link.slice(2, -2); const split = slicedS.split("|"); if (split.length == 1 && split[0] == linkText) { foundS = split[0]; } else if (split.length == 2 && split[1] == linkText) { foundS = split[0]; } } if (!!foundS) { updateDivExtraAttributes(plugin.app, plugin, el, "properties", foundS); } } } } function updateVisibleLinks(app2, plugin) { const settings = plugin.settings; app2.workspace.iterateRootLeaves((leaf) => { var _a; if (leaf.view instanceof import_obsidian68.MarkdownView && leaf.view.file) { const file = leaf.view.file; const cachedFile = app2.metadataCache.getFileCache(file); const fileName = file.path.replace(/(.*).md/, "$1"); const metadata = (_a = leaf.view) == null ? void 0 : _a.metadataEditor.contentEl; if (!!metadata) { updatePropertiesPane(metadata, file, app2, plugin); } const tabHeader = leaf.tabHeaderInnerTitleEl; if (settings.enableTabHeader) { updateDivExtraAttributes(app2, plugin, tabHeader, "tabHeader", leaf.view.file.path); } else { clearExtraAttributes(tabHeader); } if ((cachedFile == null ? void 0 : cachedFile.links) && settings.enableLinks) { cachedFile.links.forEach((link) => { var _a2; const dest = app2.metadataCache.getFirstLinkpathDest(link.link, fileName); if (dest) { const fileClassName = (_a2 = plugin.fieldIndex.filesFileClassesNames.get(dest.path)) == null ? void 0 : _a2.last(); const internalLinks = leaf.view.containerEl.querySelectorAll(`a.internal-link[href="${link.link}"]`); internalLinks.forEach((internalLink) => setLinkMetadataFormButton(plugin, internalLink, dest.path.replace(/(.*).md/, "$1"), `a.internal-link`, fileClassName)); } }); } } }); } // src/components/ExtraButton.ts var import_state4 = require("@codemirror/state"); // src/options/livePreview.ts var import_obsidian69 = require("obsidian"); var import_view3 = require("@codemirror/view"); var import_state3 = require("@codemirror/state"); var import_language4 = require("@codemirror/language"); var import_language5 = require("@codemirror/language"); function buildCMViewPlugin(plugin) { class HeaderWidget extends import_view3.WidgetType { constructor(fileClassName, after, destName) { super(); this.fileClassName = fileClassName; this.after = after; this.destName = destName; } toDOM() { let metadataMenuBtn = document.createElement("span"); if (this.fileClassName) { metadataMenuBtn.setAttr("fileclass-name", this.fileClassName); metadataMenuBtn.addClass("fileclass-icon"); metadataMenuBtn.addClass("metadata-menu"); let fileClass = plugin.fieldIndex.fileClassesName.get(this.fileClassName); const classFilesPath = plugin.settings.classFilesPath; if (classFilesPath && this.destName.includes(classFilesPath)) { const icon = (fileClass == null ? void 0 : fileClass.getIcon()) || "file-spreadsheet"; fileClass = plugin.fieldIndex.fileClassesPath.get(this.destName + ".md"); if (fileClass) { (0, import_obsidian69.setIcon)(metadataMenuBtn, icon || settings.fileClassIcon); metadataMenuBtn.onclick = (event) => { const fileClassViewManager = new FileClassViewManager(plugin, fileClass); plugin.addChild(fileClassViewManager); fileClassViewManager.build(); event.stopPropagation(); }; } } else if (fileClass) { const icon = fileClass.getIcon(); (0, import_obsidian69.setIcon)(metadataMenuBtn, icon || settings.fileClassIcon); metadataMenuBtn.onclick = (event) => { const file = plugin.app.vault.getAbstractFileByPath(`${this.destName}.md`); if (file instanceof import_obsidian69.TFile && file.extension === "md") { const noteFieldsComponent = new NoteFieldsComponent(plugin, "1", () => { }, file); plugin.addChild(noteFieldsComponent); } event.stopPropagation(); }; } } return metadataMenuBtn; } ignoreEvent() { return true; } } const settings = plugin.settings; const viewPlugin = import_view3.ViewPlugin.fromClass( class { constructor(view) { this.decorations = this.buildDecorations(view); } update(update) { if (update.docChanged || update.viewportChanged) { this.decorations = this.buildDecorations(update.view); } } destroy() { } buildDecorations(view) { let builder = new import_state3.RangeSetBuilder(); if (!settings.enableEditor) { return builder.finish(); } const mdView = view.state.field(import_obsidian69.editorInfoField); let lastAttributes = {}; let iconDecoAfter = null; let iconDecoAfterWhere = null; let mdAliasFrom = null; let mdAliasTo = null; for (let { from, to } of view.visibleRanges) { (0, import_language4.syntaxTree)(view.state).iterate({ from, to, enter: (node) => { var _a; const tokenProps = node.type.prop(import_language5.tokenClassNodeProp); if (tokenProps) { const props = new Set(tokenProps.split(" ")); const isLink = props.has("hmd-internal-link"); const isAlias2 = props.has("link-alias"); const isPipe = props.has("link-alias-pipe"); const isMDLink = props.has("link"); const isMDUrl = props.has("url"); const isMDFormatting = props.has("formatting-link"); if (isMDLink && !isMDFormatting) { mdAliasFrom = node.from; mdAliasTo = node.to; } if (!isPipe && !isAlias2) { if (iconDecoAfter && iconDecoAfterWhere) { builder.add(iconDecoAfterWhere, iconDecoAfterWhere, iconDecoAfter); iconDecoAfter = null; iconDecoAfterWhere = null; } } if (mdView.file && isLink && !isAlias2 && !isPipe || isMDUrl) { let linkText = view.state.doc.sliceString(node.from, node.to); linkText = linkText.split("#")[0]; let file = plugin.app.metadataCache.getFirstLinkpathDest(linkText, mdView.file.basename); if (isMDUrl && !file) { try { file = plugin.app.vault.getAbstractFileByPath(decodeURIComponent(linkText)); } catch (e) { } } if (file) { let fileClassName; if (plugin.settings.classFilesPath && file.path.startsWith(plugin.settings.classFilesPath)) fileClassName = file.basename; else fileClassName = (_a = plugin.fieldIndex.filesFileClassesNames.get(file.path)) == null ? void 0 : _a.last(); if (fileClassName) { const attributes = { "fileclass-name": fileClassName }; let deco = import_view3.Decoration.mark({ attributes, class: "fileclass-text" }); iconDecoAfter = import_view3.Decoration.widget({ widget: new HeaderWidget(fileClassName, true, file.path.replace(/(.*).md/, "$1")) }); if (isMDUrl && mdAliasFrom && mdAliasTo) { let deco2 = import_view3.Decoration.mark({ attributes, class: "fileclass-text" }); builder.add(mdAliasFrom, mdAliasTo, deco2); if (iconDecoAfter) { builder.add(mdAliasTo, mdAliasTo, iconDecoAfter); iconDecoAfter = null; iconDecoAfterWhere = null; mdAliasFrom = null; mdAliasTo = null; } } builder.add(node.from, node.to, deco); lastAttributes = attributes; iconDecoAfterWhere = node.to; } } } else if (isLink && isAlias2) { let deco = import_view3.Decoration.mark({ attributes: lastAttributes, class: "fileclass-text" }); builder.add(node.from, node.to, deco); if (iconDecoAfter) { builder.add(node.to, node.to, iconDecoAfter); iconDecoAfter = null; iconDecoAfterWhere = null; } } } } }); } return builder.finish(); } }, { decorations: (v) => v.decorations } ); return viewPlugin; } // src/components/ExtraButton.ts var ExtraButton = class extends import_obsidian70.Component { constructor(plugin) { super(); this.plugin = plugin; this.modalObservers = []; this.updateLinks = () => { updateVisibleLinks(this.plugin.app, this.plugin); this.observers.forEach(([observer, type, own_class]) => { const leaves = this.plugin.app.workspace.getLeavesOfType(type); leaves.forEach((leaf) => { this.updateContainer(leaf.view.containerEl, own_class, type); }); }); }; } onload() { this.plugin.registerMarkdownPostProcessor((el, ctx) => { updateElLinks(this.plugin.app, this.plugin, el, ctx); }); const ext = import_state4.Prec.lowest(buildCMViewPlugin(this.plugin)); this.plugin.registerEditorExtension(ext); this.observers = []; this.plugin.app.workspace.onLayoutReady(() => { this.initViewObservers(); this.initModalObservers(document); updateVisibleLinks(this.plugin.app, this.plugin); }); this.registerEvent(this.plugin.app.metadataCache.on("changed", (0, import_obsidian70.debounce)(this.updateLinks, 100, true))); this.registerEvent(this.plugin.app.metadataCache.on("metadata-menu:indexed", (0, import_obsidian70.debounce)(this.updateLinks, 100, true))); this.registerEvent(this.plugin.app.workspace.on("layout-change", (0, import_obsidian70.debounce)(this.updateLinks, 10, true))); this.registerEvent(this.plugin.app.workspace.on("window-open", (window2, win) => this.initModalObservers(window2.getContainer().doc))); this.registerEvent(this.plugin.app.workspace.on("layout-change", () => this.initViewObservers())); this.registerEvent(this.plugin.app.internalPlugins.getPluginById("bookmarks").instance.on("changed", (0, import_obsidian70.debounce)(this.updateLinks, 100, true))); } initViewObservers() { var _a, _b, _c, _d, _e, _f; this.observers.forEach(([observer, type]) => { observer.disconnect(); }); this.observers = []; this.registerViewType("backlink", ".tree-item-inner", true); this.registerViewType("outgoing-link", ".tree-item-inner", true); this.registerViewType("search", ".tree-item-inner", true); this.registerViewType("BC-matrix", ".BC-Link"); this.registerViewType("BC-ducks", ".internal-link"); this.registerViewType("BC-tree", "a.internal-link"); this.registerViewType("graph-analysis", ".internal-link"); this.registerViewType("starred", ".nav-file-title-content", true); this.registerViewType("file-explorer", ".nav-file-title-content", true); this.registerViewType("recent-files", ".nav-file-title-content", true); if ((_f = (_e = (_d = (_c = (_b = (_a = this.plugin.app) == null ? void 0 : _a.internalPlugins) == null ? void 0 : _b.plugins) == null ? void 0 : _c.backlink) == null ? void 0 : _d.instance) == null ? void 0 : _e.options) == null ? void 0 : _f.backlinkInDocument) { this.registerViewType("markdown", ".tree-item-inner", true); } } initModalObservers(doc) { var _a; const config = { subtree: false, childList: true, attributes: false }; this.modalObservers.push(new MutationObserver((records) => { records.forEach((mutation) => { if (mutation.type === "childList") { mutation.addedNodes.forEach((n) => { if ("className" in n && // @ts-ignore (n.className.includes("modal-container") && this.plugin.settings.enableQuickSwitcher || n.className.includes("suggestion-container") && this.plugin.settings.enableSuggestor)) { let selector = ".suggestion-title, .suggestion-note, .another-quick-switcher__item__title, .omnisearch-result__title"; if (n.className.includes("suggestion-container")) { selector = ".suggestion-title, .suggestion-note"; } this.updateContainer(n, selector, null); this._watchContainer(null, n, selector); } }); } }); })); (_a = this.modalObservers.last()) == null ? void 0 : _a.observe(doc.body, config); } registerViewType(viewTypeName, selector, updateDynamic = false) { const leaves = this.plugin.app.workspace.getLeavesOfType(viewTypeName); if (leaves.length > 1) { for (let i = 0; i < leaves.length; i++) { const container = leaves[i].view.containerEl; if (updateDynamic) { this._watchContainerDynamic(viewTypeName + i, container, selector); } else { this._watchContainer(viewTypeName + i, container, selector); } } } else if (leaves.length < 1) return; else { const container = leaves[0].view.containerEl; this.updateContainer(container, selector, viewTypeName); if (updateDynamic) { this._watchContainerDynamic(viewTypeName, container, selector); } else { this._watchContainer(viewTypeName, container, selector); } } } updateContainer(container, selector, viewTypeName) { var _a, _b; const nodes = container.findAll(selector); for (let i = 0; i < nodes.length; ++i) { const el = nodes[i]; const isCanvasFileLink = (_b = (_a = el.parentElement) == null ? void 0 : _a.getAttr("data-path")) == null ? void 0 : _b.includes(".canvas"); if (!isCanvasFileLink) { updateDivExtraAttributes(this.plugin.app, this.plugin, el, viewTypeName, ""); } } } removeFromContainer(container, selector) { const nodes = container.findAll(selector); for (let i = 0; i < nodes.length; ++i) { const el = nodes[i]; clearExtraAttributes(el); } } _watchContainer(viewType, container, selector) { let observer = new MutationObserver((records, _) => { this.updateContainer(container, selector, viewType); }); observer.observe(container, { subtree: true, childList: true, attributes: false }); if (viewType) { this.observers.push([observer, viewType, selector]); } } _watchContainerDynamic(viewType, container, selector, ownClass = "tree-item-inner", parent_class = "tree-item") { let observer = new MutationObserver((records, _) => { records.forEach((mutation) => { if (mutation.type === "childList") { mutation.addedNodes.forEach((n) => { if ("className" in n) { if (n.className.includes && typeof n.className.includes === "function" && n.className.includes(parent_class)) { const fileDivs = n.getElementsByClassName(ownClass); for (let i = 0; i < fileDivs.length; ++i) { const link = fileDivs[i]; updateDivExtraAttributes(this.plugin.app, this.plugin, link, viewType, ""); } } } }); } }); }); observer.observe(container, { subtree: true, childList: true, attributes: false }); this.observers.push([observer, viewType, selector]); } reloadObservers() { this.disconnectObservers(); this.initModalObservers(document); this.initViewObservers(); updateVisibleLinks(this.plugin.app, this.plugin); } disconnectObservers() { this.observers.forEach(([observer, type, own_class]) => { observer.disconnect(); const leaves = this.plugin.app.workspace.getLeavesOfType(type); leaves.forEach((leaf) => { this.removeFromContainer(leaf.view.containerEl, own_class); }); }); for (const observer of this.modalObservers) { observer.disconnect(); } } onunload() { this.disconnectObservers(); } }; // src/index/FieldIndex.ts var import_obsidian73 = require("obsidian"); // src/commands/updateCanvas.ts var import_obsidian71 = require("obsidian"); async function updateCanvas(plugin, forceUpdateOne) { var _a; const start2 = Date.now(); const f = plugin.fieldIndex; const dvApi = (_a = plugin.app.plugins.plugins.dataview) == null ? void 0 : _a.api; const canvases = forceUpdateOne ? [forceUpdateOne.canvas] : plugin.app.vault.getFiles().filter((t) => t.extension === "canvas"); const isNodeInGroup = (node, group) => { const { x: x1, y: y1, width: w1, height: h1 } = node; const { x: x2, y: y2, width: w2, height: h2 } = group; return x2 <= x1 && y2 <= y1 && x2 + w2 >= x1 + w1 && y2 + h2 >= y1 + h1; }; const orientedEdges = (direction, edges, node) => { switch (direction) { case "incoming": return edges.filter((edge) => edge.toNode === node.id); case "outgoing": return edges.filter((edge) => edge.fromNode === node.id); case "bothsides": return edges.filter((edge) => edge.fromNode === node.id || edge.toNode === node.id); default: return []; } }; const targetNode = (direction, edge, nodes, currentNode) => { switch (direction) { case "incoming": return nodes.find((node) => node.id !== currentNode.id && node.id === edge.fromNode); case "outgoing": return nodes.find((node) => node.id !== currentNode.id && node.id === edge.toNode); case "bothsides": return nodes.find((node) => node.id !== currentNode.id && (node.id === edge.toNode || node.id === edge.fromNode)); default: return void 0; } }; const resolveFieldLinksForNode = (field2, targetFilePath, edges, nodes, node, cumulativeSet) => { const { nodeColors, edgeColors, edgeFromSides, edgeToSides, edgeLabels, filesFromDVQuery, direction } = field2.options; const matchingFiles = filesFromDVQuery && dvApi ? new Function("dv", "current", `return ${filesFromDVQuery}`)(dvApi, dvApi.page(targetFilePath)) : void 0; const matchingEdges = orientedEdges(direction, edges, node); const linkNodes = matchingEdges.filter( (edge) => !edgeLabels || edgeLabels.length === 0 || edgeLabels.includes(edge.label) ).filter( (edge) => !edgeColors || edgeColors.length === 0 || !edge.color && edgeColors.includes("0") || edgeColors.includes(edge.color) ).filter( (edge) => !edgeFromSides || edgeFromSides.length === 0 || edgeFromSides.includes(edge.fromSide) ).filter( (edge) => !edgeToSides || edgeToSides.length === 0 || edgeToSides.includes(edge.toSide) ).map((edge) => targetNode(direction, edge, nodes, node)).filter((node2) => !!node2 && node2.type === "file").filter( (node2) => !nodeColors || nodeColors.length === 0 || !node2.color && nodeColors.includes("0") || nodeColors.includes(node2.color) ).filter((node2) => { return matchingFiles === void 0 || matchingFiles.map((f2) => f2.file.path).includes(node2.file); }); const uniqueLinkNodes = [...new Map(linkNodes.map((link) => [link.file, link])).values()]; cumulativeSet.set( field2.name, [ ...cumulativeSet.get(field2.name) || [], ...uniqueLinkNodes.filter( (link) => { var _a2; return !((_a2 = cumulativeSet.get(field2.name)) == null ? void 0 : _a2.map((link2) => link2.id).includes(link.id)); } ) ] ); }; const filterGroupsForField = (field2, canvasGroups, node) => { const { groupColors, groupLabels } = field2.options; const groupNodes = canvasGroups.filter( (group) => !groupColors || groupColors.length === 0 || !group.color && groupColors.includes("0") || groupColors.includes(group.color) ).filter( (group) => !groupLabels || groupLabels.length === 0 || groupLabels.includes(group.label) ).filter((group) => isNodeInGroup(node, group)); return groupNodes; }; const resolveFieldGroupsForNode = (field2, canvasGroups, node, cumulatedGroupsFields) => { const groupNodes = filterGroupsForField(field2, canvasGroups, node); cumulatedGroupsFields.set( field2.name, [ ...cumulatedGroupsFields.get(field2.name) || [], ...groupNodes.filter( (group) => { var _a2; return !((_a2 = cumulatedGroupsFields.get(field2.name)) == null ? void 0 : _a2.map((group2) => group2.id).includes(group.id)); } ) ] ); }; canvases.forEach(async (canvas) => { const previousFilesPaths = plugin.fieldIndex.canvasLastFiles.get(canvas.path) || []; const currentFilesPaths = []; let { nodes, edges } = { nodes: [], edges: [] }; const rawContent = await plugin.app.vault.read(canvas); if (rawContent) { try { const canvasContent = JSON.parse(rawContent); nodes = canvasContent.nodes; edges = canvasContent.edges; } catch (error) { MDM_DEBUG && console.log(error); new import_obsidian71.Notice(`Couldn't read ${canvas.path}`); } } const canvasGroups = nodes.filter((node) => node.type === "group"); const currentFiles = /* @__PURE__ */ new Map(); nodes.forEach(async (node) => { if (node.type === "file" && dvApi) { const { cumulatedLinksFields, cumulatedGroupsFields, cumulatedGroupsLinksFields } = currentFiles.get(node.file) || { cumulatedGroupsFields: /* @__PURE__ */ new Map(), cumulatedLinksFields: /* @__PURE__ */ new Map(), cumulatedGroupsLinksFields: /* @__PURE__ */ new Map() }; const targetFilePath = node.file; if (!currentFilesPaths.includes(targetFilePath)) currentFilesPaths.push(targetFilePath); const fileFields2 = f.filesFields.get(targetFilePath); const linksFields = fileFields2 == null ? void 0 : fileFields2.filter( (field2) => field2.type === "Canvas" && field2.options.canvasPath === canvas.path ); const groupsFields = fileFields2 == null ? void 0 : fileFields2.filter( (field2) => field2.type === "CanvasGroup" && field2.options.canvasPath === canvas.path ); const groupsLinksFields = fileFields2 == null ? void 0 : fileFields2.filter( (field2) => field2.type === "CanvasGroupLink" && field2.options.canvasPath === canvas.path ); linksFields == null ? void 0 : linksFields.forEach((field2) => { resolveFieldLinksForNode(field2, targetFilePath, edges, nodes, node, cumulatedLinksFields); }); groupsFields == null ? void 0 : groupsFields.forEach((field2) => { resolveFieldGroupsForNode(field2, canvasGroups, node, cumulatedGroupsFields); }); groupsLinksFields == null ? void 0 : groupsLinksFields.forEach((field2) => { const groupNodes = filterGroupsForField(field2, canvasGroups, node); groupNodes.forEach((node2) => { resolveFieldLinksForNode(field2, targetFilePath, edges, nodes, node2, cumulatedGroupsLinksFields); }); if (groupNodes.length === 0) { cumulatedGroupsLinksFields.set( field2.name, [...cumulatedGroupsLinksFields.get(field2.name) || []] ); } }); currentFiles.set(node.file, { cumulatedLinksFields, cumulatedGroupsFields, cumulatedGroupsLinksFields }); } }); currentFiles.forEach(async ({ cumulatedLinksFields, cumulatedGroupsFields, cumulatedGroupsLinksFields }, filePath) => { const file = plugin.app.vault.getAbstractFileByPath(filePath); if (file && file instanceof import_obsidian71.TFile) { const fields = plugin.fieldIndex.filesFields.get(file.path) || []; const payload = []; cumulatedLinksFields.forEach((linkNodes, name) => { const field2 = fields.find((_f) => _f.name === name); const values = linkNodes.map((node) => buildMarkDownLink(plugin, file, node.file, node.subpath)); if (field2) payload.push({ indexedPath: field2.id, payload: { value: values ? [...new Set(values)].join(",") : "" } }); }); cumulatedGroupsFields.forEach((groupNodes, name) => { const field2 = fields.find((_f) => _f.name === name); const values = groupNodes.map((group) => group.label); if (field2) payload.push({ indexedPath: field2.id, payload: { value: values ? [...new Set(values.filter((v) => !!v))].join(",") : "" } }); }); cumulatedGroupsLinksFields.forEach((linkNodes, name) => { const field2 = fields.find((_f) => _f.name === name); const values = linkNodes.map((node) => buildMarkDownLink(plugin, file, node.file, node.subpath)); if (field2) payload.push({ indexedPath: field2.id, payload: { value: values ? [...new Set(values)].join(",") : "" } }); }); if (payload.length) await postValues(plugin, payload, file); } }); previousFilesPaths.filter((f2) => !currentFilesPaths.includes(f2)).forEach(async (filePath) => { var _a2, _b, _c; const targetFile = app.vault.getAbstractFileByPath(filePath); if (targetFile && targetFile instanceof import_obsidian71.TFile) { const payload = []; const canvasFields = (_a2 = f.filesFields.get(filePath)) == null ? void 0 : _a2.filter( (field2) => field2.type === "Canvas" && field2.options.canvasPath === canvas.path ); canvasFields == null ? void 0 : canvasFields.forEach((field2) => { payload.push({ indexedPath: field2.id, payload: { value: "" } }); }); const canvasGroupFields = (_b = f.filesFields.get(filePath)) == null ? void 0 : _b.filter( (field2) => field2.type === "CanvasGroup" && field2.options.canvasPath === canvas.path ); canvasGroupFields == null ? void 0 : canvasGroupFields.forEach((field2) => { payload.push({ indexedPath: field2.id, payload: { value: "" } }); }); const canvasGroupLinksFields = (_c = f.filesFields.get(filePath)) == null ? void 0 : _c.filter( (field2) => field2.type === "CanvasGroupLink" && field2.options.canvasPath === canvas.path ); canvasGroupLinksFields == null ? void 0 : canvasGroupLinksFields.forEach((field2) => { payload.push({ indexedPath: field2.id, payload: { value: "" } }); }); if (payload.length) await postValues(plugin, payload, targetFile); } }); plugin.fieldIndex.canvasLastFiles.set(canvas.path, currentFilesPaths); }); } async function updateCanvasAfterFileClass(plugin, files = []) { var _a, _b; for (const file of files) { const index = plugin.fieldIndex; if (index.classFilesPath && !file.path.startsWith(index.classFilesPath)) { const fileClassName = (_a = index.fileClassesPath.get(file.path)) == null ? void 0 : _a.name; const canvasFields = fileClassName && ((_b = index.fileClassesFields.get(fileClassName)) == null ? void 0 : _b.filter((field2) => field2.type === "Canvas")) || []; await Promise.all(canvasFields.map(async (field2) => { const canvasFile = plugin.app.vault.getAbstractFileByPath(field2.options.canvasPath); if (canvasFile instanceof import_obsidian71.TFile && canvasFile.extension === "canvas") { await updateCanvas(plugin, { canvas: canvasFile }); } })); } } } // src/fileClass/fileClassMigration.ts var V1FileClassMigration = class { /* Moving fileClass fields definition from dataview inline fields to frontmatter yaml */ constructor(plugin) { this.plugin = plugin; } static getInlineFileClassAttributes(plugin, fileClass, excludes) { var _a; const file = fileClass.getClassFile(); let attributes = []; const dvApi = (_a = plugin.app.plugins.plugins["dataview"]) == null ? void 0 : _a.api; if (dvApi) { const dvFile = dvApi.page(file.path); try { legacyGenuineKeys(dvFile).forEach((key) => { if (key !== "file" && !Object.keys(dvFile.file.frontmatter || {}).includes(key)) { const item = typeof dvFile[key] !== "string" ? JSON.stringify(dvFile[key]) : dvFile[key]; try { const { type, options: options2, command, display, style } = JSON.parse(item); const fieldType = capitalize(type); const attr = new FileClassAttribute(plugin, key, this.name, fieldType, options2, fileClass.name, command, display, style); attributes.push(attr); } catch (e) { } } }); } catch (error) { throw error; } } if (excludes) { return attributes.filter((attr) => !excludes.includes(attr.name)); } else { return attributes; } } async migrate(fileClass) { const file = fileClass.getClassFile(); if (!fileClass.getMajorVersion() || fileClass.getMajorVersion() < 2) { const fields = []; await this.plugin.app.fileManager.processFrontMatter(file, async (fm) => { const attributes = V1FileClassMigration.getInlineFileClassAttributes(this.plugin, fileClass); attributes.forEach((attr) => { fields.push({ id: getNewFieldId(this.plugin), command: attr.command, display: attr.display, name: attr.name, options: attr.options, style: attr.style, type: attr.type, path: "" }); }); fm.fields = [...fm.fields.filter((f) => !fields.map((_f) => _f.id).includes(f.id)), ...fields]; fm.version = "2.0"; }); } } static async migrateV1FileClasses(plugin) { const index = plugin.fieldIndex; await Promise.all( [...index.v1FileClassesPath.values()].map(async (remainingV1FileClass) => { const migration = new V1FileClassMigration(plugin); await migration.migrate(remainingV1FileClass); }) ); if ([...index.v1FileClassesPath.values()].length) await index.indexFields(); } }; // src/index/FieldIndexBuilder.ts var import_obsidian72 = require("obsidian"); var FieldIndexBuilder = class extends import_obsidian72.Component { constructor(plugin) { super(); this.plugin = plugin; this.changedFiles = []; this.openFileClassManagerAfterIndex = []; this.settings = this.plugin.settings; this.init(); this.dvReady = () => { var _a, _b; return ((_a = this.dv) == null ? void 0 : _a._loaded) && !!((_b = this.plugin.app.plugins.plugins.dataview) == null ? void 0 : _b.index.initialized); }; } init() { this.flushCache(); this.filesFields = /* @__PURE__ */ new Map(); this.previousFilesFields = /* @__PURE__ */ new Map(); this.filesFieldsLastChange = /* @__PURE__ */ new Map(); this.remainingLegacyFileClasses = false; this.canvasLastFiles = /* @__PURE__ */ new Map(); this.fileFormulaFieldLastValue = /* @__PURE__ */ new Map(); this.fileFormulaFieldsStatus = /* @__PURE__ */ new Map(); this.fileLookupFieldLastOutputType = /* @__PURE__ */ new Map(); this.fileLookupFieldLastValue = /* @__PURE__ */ new Map(); this.fileLookupFieldsStatus = /* @__PURE__ */ new Map(); this.fileLookupFiles = /* @__PURE__ */ new Map(); this.dv = this.plugin.app.plugins.plugins.dataview; this.classFilesPath = this.settings.classFilesPath; this.dVRelatedFieldsToUpdate = /* @__PURE__ */ new Map(); this.bookmarks = this.plugin.app.internalPlugins.getPluginById("bookmarks"); } flushCache() { this.filesLookupsAndFormulasFields = /* @__PURE__ */ new Map(); this.filesLookupAndFormulaFieldsExists = /* @__PURE__ */ new Map(); this.fileClassesFields = /* @__PURE__ */ new Map(); this.fieldsFromGlobalFileClass = []; this.filesFieldsFromTags = /* @__PURE__ */ new Map(); this.filesFieldsFromFilesPaths = /* @__PURE__ */ new Map(); this.filesFieldsFromBookmarksGroups = /* @__PURE__ */ new Map(); this.filesFieldsFromFileClassQueries = /* @__PURE__ */ new Map(); this.filesFieldsFromInnerFileClasses = /* @__PURE__ */ new Map(); this.fileClassesPath = /* @__PURE__ */ new Map(); this.v1FileClassesPath = /* @__PURE__ */ new Map(); this.v2FileClassesPath = /* @__PURE__ */ new Map(); this.fileClassesName = /* @__PURE__ */ new Map(); this.fileClassesAncestors = /* @__PURE__ */ new Map(); this.valuesListNotePathValues = /* @__PURE__ */ new Map(); this.tagsMatchingFileClasses = /* @__PURE__ */ new Map(); this.filesPathsMatchingFileClasses = /* @__PURE__ */ new Map(); this.bookmarksGroupsMatchingFileClasses = /* @__PURE__ */ new Map(); this.filesFileClasses = /* @__PURE__ */ new Map(); this.filesFileClassesNames = /* @__PURE__ */ new Map(); this.lookupQueries = /* @__PURE__ */ new Map(); } }; // src/index/FieldIndex.ts var FieldIndex = class extends FieldIndexBuilder { constructor(plugin) { super(plugin); this.plugin = plugin; this.launchTime = Date.now(); } async onload() { this.registerEvent( this.bookmarks.instance.on("changed", async () => { if (this.bookmarks.enabled) { const updateTime = this.bookmarks.lastSave; if (this.lastBookmarkChange === void 0 || updateTime > this.lastBookmarkChange) { await this.indexFields(); this.lastBookmarkChange = updateTime; this.plugin.app.metadataCache.trigger("metadata-menu:indexed"); } } }) ); this.registerEvent( this.plugin.app.vault.on("modify", async (file) => { if (file instanceof import_obsidian73.TFile) { if (file.extension === "md") { this.changedFiles.push(file); this.lastTimeBeforeResolving = Date.now(); } else if (file.extension === "canvas") { await updateCanvas(this.plugin, { canvas: file }); } } }) ); this.registerEvent( this.plugin.app.vault.on("delete", async (file) => { this.filesFields.delete(file.path); await this.fullIndex(); }) ); this.registerEvent( this.plugin.app.vault.on("rename", async (file, oldPath) => { this.filesFields.delete(oldPath); await this.fullIndex(); }) ); this.registerEvent( this.plugin.app.metadataCache.on("resolved", async () => { if (this.plugin.app.metadataCache.inProgressTaskCount === 0 && this.plugin.launched) { if (this.changedFiles.every((file) => this.classFilesPath && file.path.startsWith(this.classFilesPath))) { this.plugin.app.metadataCache.trigger("metadata-menu:fileclass-indexed"); await updateCanvasAfterFileClass(this.plugin, this.changedFiles); } await this.indexFields(); this.plugin.app.metadataCache.trigger("metadata-menu:indexed"); this.changedFiles = []; } }) ); this.registerEvent( this.plugin.app.metadataCache.on("dataview:index-ready", async () => { MDM_DEBUG && console.log("dataview index ready"); this.dv = this.plugin.app.plugins.plugins.dataview; }) ); this.registerEvent( this.plugin.app.metadataCache.on("dataview:metadata-change", async (op, file) => { if (file.stat.mtime > this.launchTime && op === "update" && this.dvReady() && this.settings.isAutoCalculationEnabled) { const filePayloadToProcess = this.dVRelatedFieldsToUpdate.get(file.path); if (![...this.dVRelatedFieldsToUpdate.keys()].includes(file.path)) { await this.resolveAndUpdateDVQueriesBasedFields(false); } else if (filePayloadToProcess) { filePayloadToProcess.status = "processed"; } if ([...this.dVRelatedFieldsToUpdate.values()].every((item) => item.status === "processed")) this.dVRelatedFieldsToUpdate = /* @__PURE__ */ new Map(); } }) ); } indexableFiles() { return this.plugin.app.vault.getMarkdownFiles().filter((f) => !this.classFilesPath || !f.path.startsWith(this.classFilesPath)).filter((f) => !this.settings.fileIndexingExcludedFolders.some((path) => f.path.startsWith(path))).filter((f) => !this.settings.fileIndexingExcludedExtensions.some((extension) => f.path.endsWith(extension))).filter((f) => !this.settings.fileIndexingExcludedRegex.some((regexStr) => { try { const regex = new RegExp(regexStr); return regex.test(f.path); } catch (e) { return true; } })); } indexableFileClasses() { const classFilesPath = this.classFilesPath; if (classFilesPath) { return this.plugin.app.vault.getMarkdownFiles().filter((f) => f.path.startsWith(classFilesPath)); } return []; } async fullIndex(forceUpdateAll = false) { this.plugin.indexStatus.setState("indexing"); this.classFilesPath = this.plugin.settings.classFilesPath; await this.indexFields(); if (this.dvReady() && (this.settings.isAutoCalculationEnabled || forceUpdateAll)) { this.resolveAndUpdateDVQueriesBasedFields(forceUpdateAll); } if (this.remainingLegacyFileClasses) await this.migrateFileClasses(); this.plugin.app.metadataCache.trigger("metadata-menu:indexed"); } async indexFields() { let start2 = Date.now(); this.flushCache(); this.getFileClassesAncestors(); this.getFileClasses(); this.getLookupQueries(); this.resolveFileClassMatchingTags(); this.resolveFileClassMatchingFilesPaths(); this.resolveFileClassMatchingBookmarksGroups(); this.resolveFileClassQueries(); this.getFilesFieldsFromFileClass(); const indexedFiles = this.getFilesFields(); await this.getCanvasesFiles(); await this.getValuesListNotePathValues(); this.getFilesLookupAndFormulaFieldsExists(); if (this.updatedManagedField) await this.updatedManagedField.goToPreviousModal(); MDM_DEBUG && console.log("indexed FIELDS for ", indexedFiles, " files in ", (Date.now() - start2) / 1e3, "s"); } pushPayloadToUpdate(filePath, fieldsPayloadToUpdate) { const currentFieldsPayloadToUpdate = this.dVRelatedFieldsToUpdate.get(filePath) || { status: "toProcess", fieldsPayload: [] }; for (const fieldPayload of fieldsPayloadToUpdate) { currentFieldsPayloadToUpdate.status = "toProcess"; const { indexedPath, payload } = fieldPayload; const currentField = currentFieldsPayloadToUpdate == null ? void 0 : currentFieldsPayloadToUpdate.fieldsPayload.find((item) => item.indexedPath === indexedPath); if (currentField) currentField.payload = payload; else currentFieldsPayloadToUpdate.fieldsPayload.push(fieldPayload); this.dVRelatedFieldsToUpdate.set(filePath, currentFieldsPayloadToUpdate); } } async applyUpdates() { await Promise.all( [...this.dVRelatedFieldsToUpdate.keys()].map( async (filePath) => { var _a; const fieldsPayload = (_a = this.dVRelatedFieldsToUpdate.get(filePath)) == null ? void 0 : _a.fieldsPayload; if (fieldsPayload) { await postValues(this.plugin, fieldsPayload, filePath); fieldsPayload.forEach((fieldPayload) => { var _a2; const field2 = (_a2 = this.filesFields.get(filePath)) == null ? void 0 : _a2.find((_f) => _f.isRoot() && _f.id === fieldPayload.indexedPath); if (field2 && field2.type === "Lookup") this.fileLookupFieldsStatus.set(`${filePath}__${field2.name}`, "upToDate" /* upToDate */); if (field2 && field2.type === "Formula") this.fileFormulaFieldsStatus.set(`${filePath}__${field2.name}`, "upToDate" /* upToDate */); }); } } ) ); this.lastDVUpdatingTime = Date.now(); } async resolveAndUpdateDVQueriesBasedFields(force_update_all = false, forceUpdateOne) { const start2 = Date.now(); this.plugin.indexStatus.setState("indexing"); cleanRemovedLookupItemsFromIndex(this.plugin); cleanRemovedFormulasFromIndex(this.plugin); this.getFilesLookupAndFormulaFieldsExists(); resolveLookups(this.plugin); await updateLookups(this.plugin, forceUpdateOne, force_update_all); await updateFormulas(this.plugin, forceUpdateOne, force_update_all); await this.applyUpdates(); this.plugin.app.metadataCache.trigger("metadata-menu:indexed"); MDM_DEBUG && console.log("Resolved dvQ in ", (Date.now() - start2) / 1e3, "s"); } async migrateFileClasses() { await V1FileClassMigration.migrateV1FileClasses(this.plugin); this.remainingLegacyFileClasses = false; } async getCanvasesFiles() { const canvases = this.plugin.app.vault.getFiles().filter((t) => t.extension === "canvas"); canvases.forEach(async (canvas) => { const currentFilesPaths = []; let { nodes, edges } = { nodes: [], edges: [] }; const rawContent = await this.plugin.app.vault.read(canvas); if (rawContent) { try { const canvasContent = JSON.parse(rawContent); nodes = canvasContent.nodes; edges = canvasContent.edges; } catch (error) { MDM_DEBUG && console.log(error); new import_obsidian73.Notice(`Couldn't read ${canvas.path}`); } } nodes == null ? void 0 : nodes.forEach(async (node) => { if (node.type === "file") { const targetFilePath = node.file; if (!currentFilesPaths.includes(targetFilePath)) currentFilesPaths.push(targetFilePath); } }); this.canvasLastFiles.set(canvas.path, currentFilesPaths); }); } async getValuesListNotePathValues() { await Promise.all([...new Set(this.fileClassesName)].map(async ([fileClassName, fileClass]) => { await Promise.all(fileClass.attributes.map(async (attr) => { if (typeof attr.options === "object" && !!attr.options["valuesListNotePath"]) { this.valuesListNotePathValues.set( attr.options.valuesListNotePath, await FieldSetting.getValuesListFromNote( this.plugin, attr.options.valuesListNotePath ) ); } })); })); await Promise.all(this.plugin.presetFields.map(async (setting) => { if (setting.options.valuesListNotePath) { this.valuesListNotePathValues.set( setting.options.valuesListNotePath, await FieldSetting.getValuesListFromNote( this.plugin, setting.options.valuesListNotePath ) ); } })); } getFileClassesAncestors() { this.indexableFileClasses().forEach((f) => { var _a, _b; const fileClassName = getFileClassNameFromPath(this.settings, f.path); if (fileClassName) { const parent = (_b = (_a = this.plugin.app.metadataCache.getFileCache(f)) == null ? void 0 : _a.frontmatter) == null ? void 0 : _b.extends; if (parent) { const parentFile = this.plugin.app.vault.getAbstractFileByPath(`${this.classFilesPath || ""}${parent}.md`); if (parentFile) { this.fileClassesAncestors.set(fileClassName, [parent]); } else { this.fileClassesAncestors.set(fileClassName, []); } } else { this.fileClassesAncestors.set(fileClassName, []); } } }); [...this.fileClassesAncestors].forEach(([fileClassName, ancestors]) => { if (ancestors.length > 0) { this.getAncestorsRecursively(fileClassName); } }); } getAncestorsRecursively(fileClassName) { var _a; const ancestors = this.fileClassesAncestors.get(fileClassName); if (ancestors && ancestors.length) { const lastAncestor = ancestors.last(); const lastAncestorParent = (_a = this.fileClassesAncestors.get(lastAncestor)) == null ? void 0 : _a[0]; if (lastAncestorParent && lastAncestorParent !== fileClassName) { this.fileClassesAncestors.set(fileClassName, [...ancestors, lastAncestorParent]); this.getAncestorsRecursively(fileClassName); } } } getFileClasses() { this.indexableFileClasses().forEach((f) => indexFileClass(this, f)); const globalFileClass = this.settings.globalFileClass; if (!globalFileClass) { this.fieldsFromGlobalFileClass = []; } else { this.fieldsFromGlobalFileClass = this.fileClassesFields.get(globalFileClass) || []; } (async () => { await Promise.all(this.openFileClassManagerAfterIndex.map(async (fileClassName) => { const fileClass = this.fileClassesName.get(fileClassName); if (fileClass) { const fileClassViewManager = new FileClassViewManager(this.plugin, fileClass, "settingsOption"); this.plugin.addChild(fileClassViewManager); await fileClassViewManager.build(); } })); this.openFileClassManagerAfterIndex = []; })(); } getLookupQueries() { this.plugin.presetFields.filter((field2) => field2.type === "Lookup").forEach((field2) => { this.lookupQueries.set(`presetField___${field2.name}`, field2); }); [...this.fileClassesFields].forEach(([fileClassName, fields]) => { fields.filter((field2) => field2.type === "Lookup").forEach((field2) => { this.lookupQueries.set(`${fileClassName}___${field2.name}`, field2); }); }); } resolveFileClassBinding(itemMatchingFileClasses, filesFieldsFromBinding, itemToMatch, cFile) { const fileClass = itemMatchingFileClasses.get(itemToMatch); const filePath = cFile.path; if (fileClass) { this.filesFileClasses.set(filePath, [.../* @__PURE__ */ new Set([...this.filesFileClasses.get(filePath) || [], fileClass])]); this.filesFileClassesNames.set(cFile.path, [.../* @__PURE__ */ new Set([...this.filesFileClassesNames.get(filePath) || [], fileClass.name])]); const fileFileClassesFieldsFromBinding = this.fileClassesFields.get(fileClass.name); const currentFields = filesFieldsFromBinding.get(filePath); if (fileFileClassesFieldsFromBinding) { const newFields = [...fileFileClassesFieldsFromBinding]; const filteredCurrentFields = (currentFields == null ? void 0 : currentFields.filter( (field2) => { var _a, _b; return !newFields.map((f) => f.id).includes(field2.id) && !((_b = (_a = fileClass.options) == null ? void 0 : _a.excludes) == null ? void 0 : _b.map((attr) => attr.id).includes(field2.id)); } )) || []; newFields.push(...filteredCurrentFields); filesFieldsFromBinding.set(filePath, newFields); } } } resolveFileClassMatchingTags() { if (!this.tagsMatchingFileClasses.size) return; const mappedTags = [...this.tagsMatchingFileClasses.keys()].map((_t) => `#${_t}`); const filesWithMappedTag = []; this.indexableFiles().forEach((_f) => { var _a, _b; const cache = this.plugin.app.metadataCache.getFileCache(_f); const cachedTags = (_a = cache == null ? void 0 : cache.frontmatter) == null ? void 0 : _a.tags; let fileTags = []; if (Array.isArray(cachedTags)) { fileTags = cachedTags; } else if (typeof cachedTags === "string") { fileTags = cachedTags.split(",").map((_t) => _t.trim()); } const filteredTagsFromFrontmatter = fileTags.filter((_t) => mappedTags.includes(`#${_t}`)); const filteredTagsFromFile = ((_b = cache == null ? void 0 : cache.tags) == null ? void 0 : _b.filter((_t) => mappedTags.includes(_t.tag)).map((_t) => _t.tag)) || []; const filteredTags = filteredTagsFromFrontmatter.concat(filteredTagsFromFile); if (filteredTags == null ? void 0 : filteredTags.length) { const fileWithTags = { path: _f.path, tags: [] }; filteredTags.forEach((_t) => fileWithTags.tags.push(_t)); filesWithMappedTag.push(fileWithTags); } }); filesWithMappedTag.forEach((cFile) => { cFile.tags.forEach((_tag) => { const tag = _tag.replace(/^\#/, ""); this.resolveFileClassBinding( this.tagsMatchingFileClasses, this.filesFieldsFromTags, tag, cFile ); }); }); } resolveFileClassMatchingFilesPaths() { if (!this.filesPathsMatchingFileClasses.size) return; const paths = [...this.filesPathsMatchingFileClasses.keys()]; this.indexableFiles().filter((_f) => _f.parent !== null).forEach((file) => { for (const path of paths) { if (file.parent.path.startsWith(path)) { this.resolveFileClassBinding( this.filesPathsMatchingFileClasses, this.filesFieldsFromFilesPaths, path, file ); } } }); } getFilesForItems(items, groups, filesWithGroups, path = "") { if (groups.includes(path || "/")) { items.filter((_i) => _i.type === "file").forEach((_i) => filesWithGroups.push({ path: _i.path, group: path || "/" })); } for (const group of items.filter((_i) => _i.type === "group")) { const subPath = `${path}${path ? "/" : ""}${group.title}`; this.getFilesForItems(group.items || [], groups, filesWithGroups, subPath); } } resolveFileClassMatchingBookmarksGroups() { if (!this.bookmarksGroupsMatchingFileClasses.size) return; const groups = [...this.bookmarksGroupsMatchingFileClasses.keys()]; const bookmarks = this.bookmarks; if (!bookmarks.enabled) return; const filesWithGroups = []; this.getFilesForItems(bookmarks.instance.items || [], groups, filesWithGroups); filesWithGroups.forEach((cFile) => { this.resolveFileClassBinding( this.bookmarksGroupsMatchingFileClasses, this.filesFieldsFromBookmarksGroups, cFile.group, cFile ); }); } resolveFileClassQueries() { var _a; const dvApi = (_a = this.plugin.app.plugins.plugins.dataview) == null ? void 0 : _a.api; if (!dvApi) return; this.settings.fileClassQueries.forEach((sfcq) => { const fcq = new FileClassQuery_default(sfcq.name, sfcq.id, sfcq.query, sfcq.fileClassName); fcq.getResults(dvApi).forEach((result) => { const fileClass = this.fileClassesName.get(fcq.fileClassName); if (fileClass) { const f = result.file; this.filesFileClasses.set(f.path, [.../* @__PURE__ */ new Set([...this.filesFileClasses.get(f.path) || [], fileClass])]); this.filesFileClassesNames.set(f.path, [.../* @__PURE__ */ new Set([...this.filesFileClassesNames.get(f.path) || [], fileClass.name])]); } const fileFileClassesFieldsFromQuery = this.fileClassesFields.get(fcq.fileClassName); if (fileFileClassesFieldsFromQuery) this.filesFieldsFromFileClassQueries.set(result.file.path, fileFileClassesFieldsFromQuery); }); }); } getFilesFieldsFromFileClass() { this.indexableFiles().forEach((f) => { var _a, _b; const fileFileClassesNames = []; const fileClassesCache = (_b = (_a = this.plugin.app.metadataCache.getFileCache(f)) == null ? void 0 : _a.frontmatter) == null ? void 0 : _b[this.settings.fileClassAlias]; if (fileClassesCache) { Array.isArray(fileClassesCache) ? fileFileClassesNames.push(...fileClassesCache) : fileFileClassesNames.push(...fileClassesCache.split(",").map((fcn) => fcn.trim())); fileFileClassesNames.forEach((fileFileClassName) => { const fileClass = this.fileClassesName.get(fileFileClassName); if (fileClass) { this.filesFileClasses.set(f.path, [.../* @__PURE__ */ new Set([...this.filesFileClasses.get(f.path) || [], fileClass])]); this.filesFileClassesNames.set(f.path, [.../* @__PURE__ */ new Set([...this.filesFileClassesNames.get(f.path) || [], fileClass.name])]); const fileClassesFieldsFromFile = this.fileClassesFields.get(fileFileClassName); const currentFields = this.filesFieldsFromInnerFileClasses.get(f.path); if (fileClassesFieldsFromFile) { const newFields = [...fileClassesFieldsFromFile]; const filteredCurrentFields = (currentFields == null ? void 0 : currentFields.filter( (field2) => { var _a2, _b2; return !newFields.map((f2) => f2.id).includes(field2.id) && !((_b2 = (_a2 = fileClass.options) == null ? void 0 : _a2.excludes) == null ? void 0 : _b2.map((attr) => attr.id).includes(field2.id)); } )) || []; newFields.push(...filteredCurrentFields); this.filesFieldsFromInnerFileClasses.set(f.path, newFields); } else { this.filesFieldsFromInnerFileClasses.set(f.path, []); } } else { this.filesFieldsFromInnerFileClasses.set(f.path, []); } }); } else { this.filesFieldsFromInnerFileClasses.set(f.path, []); } }); } isLookupOrFormula(field2) { return ["Lookup", "Formula"].includes(field2.type); } getFilesFields() { const filesToIndex = this.indexableFiles().filter( (_f) => !this.changedFiles.length || //forceupdateAll this.changedFiles.filter((file) => this.classFilesPath && file.path.startsWith(this.classFilesPath)).length || // a fileclass has changed forceupdate all this.changedFiles.includes(_f) ); filesToIndex.forEach((f) => { var _a; const fileFieldsFromInnerFileClasses = this.filesFieldsFromInnerFileClasses.get(f.path); const fileFieldsFromQuery = this.filesFieldsFromFileClassQueries.get(f.path); const fileFieldsFromTag = this.filesFieldsFromTags.get(f.path); const fileFieldsFromPath = this.filesFieldsFromFilesPaths.get(f.path); const fileFieldsFromGroup = this.filesFieldsFromBookmarksGroups.get(f.path); let fileFields2; const previousFileFields = ((_a = this.previousFilesFields.get(f.path)) == null ? void 0 : _a.map((_f) => _f.id)) || []; if ((fileFieldsFromInnerFileClasses == null ? void 0 : fileFieldsFromInnerFileClasses.length) || (fileFieldsFromQuery == null ? void 0 : fileFieldsFromQuery.length) || (fileFieldsFromTag == null ? void 0 : fileFieldsFromTag.length) || (fileFieldsFromPath == null ? void 0 : fileFieldsFromPath.length) || (fileFieldsFromGroup == null ? void 0 : fileFieldsFromGroup.length)) { fileFields2 = fileFieldsFromInnerFileClasses || []; fileFields2.push(...(fileFieldsFromTag || []).filter((field2) => !fileFields2.map((f2) => f2.id).includes(field2.id))); fileFields2.push(...(fileFieldsFromPath || []).filter((field2) => !fileFields2.map((f2) => f2.id).includes(field2.id))); fileFields2.push(...(fileFieldsFromGroup || []).filter((field2) => !fileFields2.map((f2) => f2.id).includes(field2.id))); fileFields2.push(...(fileFieldsFromQuery || []).filter((field2) => !fileFields2.map((f2) => f2.id).includes(field2.id))); this.filesFields.set(f.path, fileFields2); const filesLookupAndFormulasFields = fileFields2.filter((f2) => this.isLookupOrFormula(f2)); filesLookupAndFormulasFields.push(...(fileFieldsFromTag || []).filter((field2) => !filesLookupAndFormulasFields.map((f2) => f2.id).includes(field2.id) && this.isLookupOrFormula(field2))); filesLookupAndFormulasFields.push(...(fileFieldsFromPath || []).filter((field2) => !filesLookupAndFormulasFields.map((f2) => f2.id).includes(field2.id) && this.isLookupOrFormula(field2))); filesLookupAndFormulasFields.push(...(fileFieldsFromGroup || []).filter((field2) => !filesLookupAndFormulasFields.map((f2) => f2.id).includes(field2.id) && this.isLookupOrFormula(field2))); filesLookupAndFormulasFields.push(...(fileFieldsFromQuery || []).filter((field2) => !filesLookupAndFormulasFields.map((f2) => f2.id).includes(field2.id) && this.isLookupOrFormula(field2))); if (filesLookupAndFormulasFields.length) this.filesLookupsAndFormulasFields.set(f.path, filesLookupAndFormulasFields); } else if (this.fieldsFromGlobalFileClass.length) { fileFields2 = this.fieldsFromGlobalFileClass; this.filesFields.set(f.path, fileFields2); const filesLookupAndFormulasFields = this.fieldsFromGlobalFileClass.filter((f2) => this.isLookupOrFormula(f2)); if (filesLookupAndFormulasFields.length) this.filesLookupsAndFormulasFields.set(f.path, this.fieldsFromGlobalFileClass.filter((f2) => this.isLookupOrFormula(f2))); this.filesFileClasses.set(f.path, [this.fileClassesName.get(this.settings.globalFileClass)]); this.filesFileClassesNames.set(f.path, [this.settings.globalFileClass]); } else { fileFields2 = this.plugin.presetFields.map((prop) => { const property = new (buildEmptyField(this.plugin, void 0))(); return Object.assign(property, prop); }); this.filesFields.set(f.path, fileFields2); const filesLookupAndFormulasFields = fileFields2.filter((f2) => this.isLookupOrFormula(f2)); if (filesLookupAndFormulasFields.length) this.filesLookupsAndFormulasFields.set(f.path, fileFields2.filter((f2) => this.isLookupOrFormula(f2))); } if (fileFields2.some((f2) => !(previousFileFields == null ? void 0 : previousFileFields.includes(f2.id))) || (previousFileFields == null ? void 0 : previousFileFields.some((fId) => !fileFields2.map((_f) => _f.id).includes(fId)))) { this.filesFieldsLastChange.set(f.path, Date.now()); } this.previousFilesFields.set(f.path, fileFields2); }); return filesToIndex.length; } getFilesLookupAndFormulaFieldsExists(file) { if (!this.dvReady()) return; [...this.filesFields.entries()].forEach(([filePath, fields]) => { const dvFormulaFields = fields.filter( (f) => f.isRoot() && f.type === "Formula" && this.dv.api.page(filePath) && f.name in this.dv.api.page(filePath) ); if (!this.settings.isAutoCalculationEnabled) dvFormulaFields.forEach((field2) => this.fileFormulaFieldsStatus.set(`${filePath}__${field2.name}`, "mayHaveChanged" /* mayHaveChanged */)); const dvLookupFields = fields.filter( (f) => f.isRoot() && f.type === "Lookup" && this.dv.api.page(filePath) && f.name in this.dv.api.page(filePath) ); if (!this.settings.isAutoCalculationEnabled) dvLookupFields.forEach((field2) => this.fileLookupFieldsStatus.set(`${filePath}__${field2.name}`, "mayHaveChanged" /* mayHaveChanged */)); this.filesLookupAndFormulaFieldsExists.set(filePath, [...dvFormulaFields, ...dvLookupFields]); }); } dvQFieldChanged(path) { var _a; let changed = false; (_a = this.filesLookupAndFormulaFieldsExists.get(path)) == null ? void 0 : _a.forEach((field2) => { if (field2.type === "Lookup") { changed = changed || this.fileLookupFieldsStatus.get(path + "__" + field2.name) === "changed" /* changed */; } else if (field2.type === "Formula") { changed = changed || this.fileFormulaFieldsStatus.get(path + "__" + field2.name) === "changed" /* changed */; } }); return changed; } dvQFieldMayHaveChanged(path) { var _a; let changed = false; (_a = this.filesLookupAndFormulaFieldsExists.get(path)) == null ? void 0 : _a.forEach((field2) => { if (field2.type === "Lookup") { changed = changed || this.fileLookupFieldsStatus.get(path + "__" + field2.name) === "mayHaveChanged" /* mayHaveChanged */; } else if (field2.type === "Formula") { changed = changed || this.fileFormulaFieldsStatus.get(path + "__" + field2.name) === "mayHaveChanged" /* mayHaveChanged */; } }); return changed; } dvQFieldHasAnError(path) { var _a; let changed = false; (_a = this.filesLookupAndFormulaFieldsExists.get(path)) == null ? void 0 : _a.forEach((field2) => { if (field2.type === "Lookup") { changed = changed || this.fileLookupFieldsStatus.get(path + "__" + field2.name) === "error" /* error */; } else if (field2.type === "Formula") { changed = changed || this.fileFormulaFieldsStatus.get(path + "__" + field2.name) === "error" /* error */; } }); return changed; } isIndexed(file) { this.indexableFiles().map((f) => f.path).includes(file.path); return true; } }; // src/components/IndexStatus.ts var import_obsidian74 = require("obsidian"); var Statuses = /* @__PURE__ */ ((Statuses2) => { Statuses2["indexing"] = "indexing"; Statuses2["indexed"] = "indexed"; Statuses2["update"] = "update"; return Statuses2; })(Statuses || {}); var statusIcon2 = { "indexing": ` `, "indexed": ` `, "update": ` ` }; var statusTooltip = { "indexing": "Metadata Menu: indexing fields", "indexed": "Metadata Menu: field index complete", "update": "Click to update lookups and formulas" }; var IndexStatus = class extends import_obsidian74.Component { constructor(plugin) { super(); this.plugin = plugin; this.state = "indexed" /* indexed */; } setState(state) { this.state = state; this.statusBtn.setTooltip(statusTooltip[state], { placement: "top" }); for (const status in Statuses) { this.statusIcon.removeClass(status); } this.statusIcon.addClass(state); this.statusIcon.innerHTML = statusIcon2[state]; } onload() { const indexStatus = this.plugin.addStatusBarItem(); const container = indexStatus.createEl("div", { cls: "status-bar-item-segment index-status" }); if (!this.plugin.settings.showIndexingStatusInStatusBar) container.hide(); this.statusBtn = new import_obsidian74.ButtonComponent(container); this.statusBtn.setClass("status-item-btn"); this.statusIcon = this.statusBtn.buttonEl.createEl("span", { cls: "status-bar-item-icon sync-status-icon" }); this.setState("indexed"); this.statusBtn.onClick(async () => { let updatesToApply = false; if (this.state === "update") { const dvQFields = this.getdvQFieldsToUpdate(); await Promise.all( dvQFields.map(async (field2) => { if (this.file) { if (field2.type === "Lookup") { await updateLookups(this.plugin, { file: this.file, fieldName: field2.name }); updatesToApply = true; } else if (field2.type === "Formula") { await updateFormulas(this.plugin, { file: this.file, fieldName: field2.name }); updatesToApply = true; } } }) ); } if (updatesToApply) this.plugin.fieldIndex.applyUpdates(); }); } getdvQFieldsToUpdate() { if (this.file) { const index = this.plugin.fieldIndex; const fileDVQFields = index.filesLookupsAndFormulasFields.get(this.file.path) || []; return fileDVQFields.filter((field2) => ["Lookup", "Formula"].includes(field2.type)); } return []; } checkForUpdate(view) { if (view && view instanceof import_obsidian74.FileView && view.file) { const file = this.plugin.app.vault.getAbstractFileByPath(view.file.path); if (file instanceof import_obsidian74.TFile && file.extension === "md") { this.file = file; if (this.plugin.fieldIndex.dvQFieldChanged(file.path)) { this.setState("update"); } else if (this.plugin.fieldIndex.dvQFieldMayHaveChanged(file.path)) { this.setState("update"); } else { this.setState("indexed"); } } else { this.file = void 0; } } else { this.file = void 0; } } }; // src/commands/fieldModifier.ts var import_obsidian75 = require("obsidian"); function buildAndOpenModal(plugin, file, fieldName, attrs) { var _a, _b; const field2 = (_a = plugin.fieldIndex.filesFields.get(file.path)) == null ? void 0 : _a.find((f) => f.isRoot() && f.name === fieldName); if (field2) { if ((_b = attrs == null ? void 0 : attrs.options) == null ? void 0 : _b.inFrontmatter) { const fieldVM = fieldValueManager(plugin, field2.id, field2.fileClassName, file, void 0, void 0, -1); fieldVM == null ? void 0 : fieldVM.openModal(); } else { new chooseSectionModal( plugin, file, (lineNumber, asList, asBlockquote) => { const fieldVM = fieldValueManager(plugin, field2.id, field2.fileClassName, file, void 0, void 0, lineNumber, asList, asBlockquote); fieldVM == null ? void 0 : fieldVM.openModal(); } ).open(); } } } function fieldModifier(plugin, dv, p, fieldName, attrs = {}) { var _a; attrs.cls = (attrs == null ? void 0 : attrs.cls) || {} + "value-container"; const fieldContainer = dv.el("div", ""); fieldContainer.setAttr("class", `metadata-menu-dv-field-container ${fieldName}`); const file = plugin.app.vault.getAbstractFileByPath(p.file.path); if (!(file instanceof import_obsidian75.TFile && file.extension == "md")) { throw Error("path doesn't correspond to a proper file"); } const { indexedPath, field: field2 } = getFullIndexedPathFromDottedPath(fieldName, plugin.fieldIndex.filesFields.get(file.path)); const fieldSegments = fieldName.replaceAll("[", ".").replaceAll("]", "").split("."); const fieldValue = fieldSegments.reduce((acc, cur) => acc == null ? void 0 : acc[cur], p); if (fieldValue === void 0) { if (!((_a = attrs == null ? void 0 : attrs.options) == null ? void 0 : _a.showAddField)) { const emptyField = dv.el("span", null, attrs); fieldContainer.appendChild(emptyField); return fieldContainer; } const addFieldBtn = dv.el("button", attrs); (0, import_obsidian75.setIcon)(addFieldBtn, positionIcon.inline); addFieldBtn.onclick = async () => { if (field2) { buildAndOpenModal(plugin, file, fieldName, attrs); } else { new chooseSectionModal( plugin, file, (lineNumber, asList, asBlockquote) => { const fieldVM = new (FieldValueManager(plugin, field2, file, void 0, indexedPath, lineNumber, asList, asBlockquote))(); fieldVM == null ? void 0 : fieldVM.openModal(); } ).open(); } }; fieldContainer.appendChild(addFieldBtn); const addInFrontmatterFieldBtn = dv.el("button", attrs); (0, import_obsidian75.setIcon)(addInFrontmatterFieldBtn, positionIcon.yaml); addInFrontmatterFieldBtn.onclick = async () => { if (field2) { const _field = buildField(plugin, field2.name, field2.id, field2.path, field2.fileClassName, field2.command, field2.display, field2.style, field2.type, {}); const fieldVM = new (FieldValueManager(plugin, _field, file, void 0, indexedPath, -1, false, false))(); fieldVM == null ? void 0 : fieldVM.openModal(); } }; fieldContainer.appendChild(addInFrontmatterFieldBtn); } else { if (field2 && (field2 == null ? void 0 : field2.type)) { const fieldVM = fieldValueManager(plugin, field2.id, field2.fileClassName, file, void 0, indexedPath); if (!fieldVM) { return fieldContainer; } fieldVM.value = fieldValue; if (field2.type === "ObjectList" && !isNaN(parseInt(fieldSegments.last()))) { const index = parseInt(fieldSegments.last()); const editBtn = fieldContainer.createEl("button"); const displayValue30 = dv.el("span", displayItem(fieldVM, fieldValue, parseInt(fieldSegments.last())) || "", attrs); fieldContainer.appendChild(displayValue30); (0, import_obsidian75.setIcon)(editBtn, getIcon("Object")); editBtn.onclick = async () => { const upperObjectListEF = await Note.getExistingFieldForIndexedPath(plugin, file, indexedPath.replace(/\[\d+\]$/, "")); const item = (await (upperObjectListEF == null ? void 0 : upperObjectListEF.getChildrenFields(fieldVM.plugin, fieldVM.target)) || [])[index]; const itemFVM = getPseudoObjectValueManagerFromObjectItem(fieldVM, item); itemFVM.openModal(); }; } else { createDvField23(fieldVM, dv, p, fieldContainer, attrs); } } else { const field3 = buildField(plugin, fieldName, "", "", void 0, void 0, void 0, void 0, "Input", {}); const fieldVM = new (FieldValueManager(plugin, field3, file, void 0, indexedPath))(); fieldVM.value = fieldValue; createDvField23(fieldVM, dv, p, fieldContainer, attrs); } } return fieldContainer; } function getFullIndexedPathFromDottedPath(dottedPath, fileFields2) { const dottedFields = dottedPath.replaceAll("[", ".").replaceAll("]", "").split("."); var parent = ""; const fields = []; for (const field2 of dottedFields) { const f = fileFields2 == null ? void 0 : fileFields2.find((x) => x.name === field2 && x.path === parent); if (f) { fields.push(f); parent = `${f.path}${f.isRoot() ? "" : "____"}${f.id}`; } } fields.forEach((x) => dottedPath = dottedPath.replaceAll(x.name, x.id)); return { indexedPath: dottedPath.replaceAll(".", "____"), field: fields[fields.length - 1] }; } // src/commands/fileFields.ts var import_obsidian76 = require("obsidian"); var FieldInfo = class { constructor(plugin, file, eF) { this.plugin = plugin; this.file = file; this.eF = eF; } getInfos() { const field2 = this.eF.field; const fieldVM = fieldValueManager(this.plugin, field2.id, field2.fileClassName, this.file, void 0); fieldVM.value = this.eF.value; return { indexedPath: this.eF.indexedPath, name: this.eF.field.name, value: this.eF.value, fileClassName: this.eF.field.fileClassName, type: this.eF.field.type, isValid: !fieldVM.value || validateValue25(fieldVM.type)(fieldVM), id: this.eF.field.id, ignoredInMenu: this.plugin.settings.globallyIgnoredFields.includes(this.eF.field.name), options: this.eF.field.options, sourceType: this.eF.field.fileClassName ? "fileClass" : "settings" }; } }; async function fileExistingFields(plugin, fileOrfilePath) { let file; if (fileOrfilePath instanceof import_obsidian76.TFile) { file = fileOrfilePath; } else { const _file = plugin.app.vault.getAbstractFileByPath(fileOrfilePath); if (_file instanceof import_obsidian76.TFile && _file.extension == "md") { file = _file; } else { throw Error("path doesn't correspond to a proper file"); } } const eFs = await Note.getExistingFields(plugin, file); return [eFs, file]; } async function fileFields(plugin, fileOrfilePath) { const [eFs, file] = await fileExistingFields(plugin, fileOrfilePath); const fields = {}; for (const eF of eFs) { if (eF.indexedPath) fields[eF.indexedPath] = new FieldInfo(plugin, file, eF).getInfos(); } return fields; } async function namedFileFields(plugin, fileOrfilePath) { const [eFs, file] = await fileExistingFields(plugin, fileOrfilePath); const fields = {}; for (const eF of eFs) { if (!eF.indexedPath) continue; const namedIndexedPath = getNamedIndexedPath(plugin, file, eF.indexedPath); if (namedIndexedPath) fields[namedIndexedPath] = new FieldInfo(plugin, file, eF).getInfos(); } return fields; } // src/commands/postNamedFieldsValues.ts var import_obsidian77 = require("obsidian"); var inlineFieldRegex = (attribute) => `(?>*(\\s+)?)?(?- )?(?(\\s+)?)?(?[_\\*~\`]*)(?${attribute})(?[_\\*~\`]*)(?\\s*)::(?\\s*)`; var LocationWrapper = { "fullLine": { start: "", end: "" }, "brackets": { start: "[", end: "]" }, "parenthesis": { start: "(", end: ")" } }; async function postNamedFieldsValues(plugin, payload, fileOrFilePath, lineNumber, after = true, asList = false, asComment = false) { var _a; if (payload.some((_payload) => !_payload.name)) { console.error("One payload's field is missing a name"); return; } const file = getFileFromFileOrPath(plugin, fileOrFilePath); const eFs = await Note.getExistingFields(plugin, file); const cache = plugin.app.metadataCache.getFileCache(file); const frontmatter = cache == null ? void 0 : cache.frontmatter; const { start: start2, end: end2 } = getFrontmatterPosition(plugin, file); const dvAPi = (_a = plugin.app.plugins.plugins.dataview) == null ? void 0 : _a.api; const inFrontmatter = !!(lineNumber === -1 || lineNumber && start2 && end2 && lineNumber >= start2.line && lineNumber <= end2.line); const toCreateInline = {}; const toUpdateInline = {}; const toYaml = {}; payload.forEach(async (item) => { const create = !legacyGenuineKeys(dvAPi.page(file.path)).includes(item.name); if (create) { if (!lineNumber || inFrontmatter) { toYaml[item.name] = item.payload; } else { toCreateInline[item.name] = item.payload; } } else { if (frontmatter && Object.keys(frontmatter).includes(item.name)) { toYaml[item.name] = item.payload; } else { toUpdateInline[item.name] = item.payload; } } }); if (Object.keys(toYaml).length) { await plugin.app.fileManager.processFrontMatter(file, (fm) => { Object.keys(toYaml).forEach((key) => { fm[key] = toYaml[key].value; }); }); } if (Object.keys(toCreateInline).length || Object.keys(toUpdateInline).length) { postFieldsInline(plugin, file, toUpdateInline, toCreateInline, lineNumber, after, asList, asComment); } } var matchInlineFields = (regex, line, attribute, input, location = "fullLine", style) => { const sR = line.matchAll(regex); let next = sR.next(); const newFields = []; while (!next.done) { const match = next.value; if (match.groups && Object.keys(match.groups).every((j) => fieldComponents.includes(j))) { const { inList, inQuote, preSpacer, startStyle, endStyle, beforeSeparatorSpacer, afterSeparatorSpacer, values } = match.groups; const inputArray = input ? input.replace(/(\,\s+)/g, ",").split(",") : [""]; const newValue = inputArray.length == 1 ? inputArray[0] : `${inputArray.join(", ")}`; const start2 = LocationWrapper[location].start; const end2 = LocationWrapper[location].end; const targetStartStyle = style ? buildStartStyle(style) : startStyle; const targetEndStyle = style ? buildEndStyle(style) : endStyle; newFields.push({ oldField: match[0], newField: `${inQuote || ""}${start2}${inList || ""}${preSpacer || ""}${targetStartStyle}${attribute}${targetEndStyle}${beforeSeparatorSpacer}::${afterSeparatorSpacer || " "}${newValue}${end2}` }); } next = sR.next(); } return newFields; }; async function postFieldsInline(plugin, file, fieldsToUpdate, fieldsToCreate, lineNumber, after = true, asList = false, asComment = false) { var _a; const skippedLines = []; let newContent = []; const currentContent = await plugin.app.vault.read(file); currentContent.split("\n").forEach((line, _lineNumber) => { if (_lineNumber == lineNumber) { if (after) newContent.push(line); Object.entries(fieldsToCreate).forEach(([fieldName, payload]) => { const startStyle = payload.style ? buildStartStyle(payload.style) : ""; const endStyle = payload.style ? buildEndStyle(payload.style) : ""; const newLine = `${asComment ? ">" : ""}${asList ? "- " : ""}${startStyle}${fieldName}${endStyle}:: ${payload.value}`; newContent.push(newLine); }); if (!after) newContent.push(line); } else { newContent.push(line); } }); const updateContentWithField = (content, fieldName, payload) => { return content.map((line, i) => { const encodedInput = encodeLink(payload.value); let encodedLine = encodeLink(line); const fullLineRegex2 = new RegExp(`^${inlineFieldRegex(fieldName)}(?[^\\]]*)`, "u"); const fR = encodedLine.match(fullLineRegex2); if ((fR == null ? void 0 : fR.groups) && Object.keys(fR.groups).every((j) => fieldComponents.includes(j))) { const { inList, inQuote, preSpacer, startStyle, endStyle, beforeSeparatorSpacer, afterSeparatorSpacer, values } = fR.groups; const targetStartStyle = payload.style ? buildStartStyle(payload.style) : startStyle; const targetEndStyle = payload.style ? buildEndStyle(payload.style) : endStyle; const inputArray = payload.value ? payload.value.replace(/(\,\s+)/g, ",").split(",").sort() : []; let newValue; let hiddenValue = ""; let emptyLineAfterList = ""; newValue = inputArray.length == 1 ? inputArray[0] : `${inputArray.join(", ")}`; return `${inQuote || ""}${inList || ""}${preSpacer || ""}${targetStartStyle}${fieldName}${targetEndStyle}${beforeSeparatorSpacer}::${afterSeparatorSpacer || " "}${hiddenValue + newValue + emptyLineAfterList}`; } else { const newFields = []; const inSentenceRegexBrackets2 = new RegExp(`\\[${inlineFieldRegex(fieldName)}(?[^\\]]+)?\\]`, "gu"); const inSentenceRegexPar2 = new RegExp(`\\(${inlineFieldRegex(fieldName)}(?[^\\)]+)?\\)`, "gu"); newFields.push(...matchInlineFields(inSentenceRegexBrackets2, encodedLine, fieldName, encodedInput, "brackets" /* brackets */, payload.style)); newFields.push(...matchInlineFields(inSentenceRegexPar2, encodedLine, fieldName, encodedInput, "parenthesis" /* parenthesis */, payload.style)); newFields.forEach((field2) => { const fieldRegex = new RegExp(field2.oldField.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "u"); encodedLine = encodedLine.replace(fieldRegex, field2.newField); }); return decodeLink(encodedLine); } }); }; Object.entries(fieldsToUpdate).forEach(([fieldName, payload]) => { newContent = updateContentWithField(newContent, fieldName, payload); }); const updatedFile = newContent.filter((line, i) => !skippedLines.includes(i)).join("\n"); await plugin.app.vault.modify(file, updatedFile); const editor = (_a = plugin.app.workspace.getActiveViewOfType(import_obsidian77.MarkdownView)) == null ? void 0 : _a.editor; if (editor) { const lineNumber2 = editor.getCursor().line; editor.setCursor({ line: editor.getCursor().line, ch: editor.getLine(lineNumber2).length }); } } // src/MetadataMenuApi.ts var MetadataMenuApi = class { constructor(plugin) { this.plugin = plugin; } make() { return { getValues: this.getValues(), getValuesForIndexedPath: this.getValuesForIndexedPath(), fieldModifier: this.fieldModifier(), fileFields: this.fileFields(), namedFileFields: this.namedFileFields(), insertMissingFields: this.insertMissingFields(), postValues: this.postValues(), postNamedFieldsValues: this.postNamedFieldsValues() }; } getValues() { return async (fileOrFilePath, attribute) => getValues(this.plugin, fileOrFilePath, attribute); } getValuesForIndexedPath() { return async (fileOrFilePath, indexedPath) => getValuesForIndexedPath(this.plugin, fileOrFilePath, indexedPath); } fieldModifier() { return (dv, p, fieldName, attrs) => fieldModifier(this.plugin, dv, p, fieldName, attrs); } fileFields() { return async (fileOrFilePath) => fileFields(this.plugin, fileOrFilePath); } namedFileFields() { return async (fileOrFilePath) => namedFileFields(this.plugin, fileOrFilePath); } insertMissingFields() { return async (fileOrFilePath, lineNumber, asList, asBlockquote, fileClassName) => insertMissingFields(this.plugin, fileOrFilePath, lineNumber, asList, asBlockquote, fileClassName); } postValues() { return async (fileOrFilePath, payload, lineNumber, asList, asBlockquote) => postValues(this.plugin, payload, fileOrFilePath, lineNumber, asList, asBlockquote); } postNamedFieldsValues() { return async (fileOrFilePath, payload, lineNumber, asList, asBlockquote) => postNamedFieldsValues(this.plugin, payload, fileOrFilePath, lineNumber, asList, asBlockquote); } }; // src/types/selectValuesSourceTypes.ts var Key = { "ValuesList": "valuesList", "ValuesListNotePath": "valuesListNotePath", "ValuesFromDVQuery": "valuesFromDVQuery" }; // src/settings/migrateSetting.ts var migrateSettings = async (plugin) => { if (plugin.settings.settingsVersion === void 0) await migrateSettingsV1toV2(plugin); if (plugin.settings.settingsVersion === 2) await migrateSettingsV2toV3(plugin); if (plugin.settings.settingsVersion === 3) await migrateSettingsV3toV4(plugin); if (plugin.settings.settingsVersion === 4) await migrateSettingsV4toV5(plugin); }; var migrateSettingsV1toV2 = async (plugin) => { const presetFields = plugin.presetFields; presetFields.forEach((p) => { if (!Object.keys(p).contains("type")) { if (p.isMulti) p.type = "Multi"; else if (p.isCycle) p.type = "Cycle"; else if (p.isBoolean) p.type = "Boolean"; else if (p.options && Object.keys(p.options).length > 0) p.type = "Select"; else p.type = "Input"; } delete p.isMulti; delete p.isCycle; delete p.isBoolean; if (Object.getOwnPropertyDescriptor(p, "values") !== void 0) { Object.defineProperty( p, "options", Object.getOwnPropertyDescriptor(p, "values") ); delete p["values"]; } }); plugin.settings.settingsVersion = 2; await plugin.saveData(plugin.settings); MDM_DEBUG && console.log("Metadata menu settings migrated to version 2"); }; var migrateSettingsV2toV3 = async (plugin) => { const presetFields = plugin.presetFields; presetFields.forEach((p) => { if (["Select", "Multi"].includes(p.type)) { const currentOptionKeys = Object.keys(p.options); p.options.valuesList = {}; currentOptionKeys.forEach((key) => p.options.valuesList[key] = p.options[key]); if (p.valuesListNotePath) { const selectType = "ValuesListNotePath" /* ValuesListNotePath */; p.options.sourceType = selectType; p.options[Key[selectType]]; } else { p.options.sourceType = "ValuesList" /* ValuesList */; } p.options.valuesListNotePath = p.valuesListNotePath; currentOptionKeys.forEach((key) => delete p.options[key]); p.options.valuesFromDVQuery = ""; } delete p.valuesListNotePath; }); plugin.settings.settingsVersion = 3; await plugin.saveData(plugin.settings); MDM_DEBUG && console.log("Metadata menu settings migrated to version 3"); }; var migrateSettingsV3toV4 = async (plugin) => { plugin.settings.fileClassExcludedFolders = []; plugin.settings.settingsVersion = 4; await plugin.saveData(plugin.settings); MDM_DEBUG && console.log("Metadata menu settings migrated to version 4"); }; var migrateSettingsV4toV5 = async (plugin) => { plugin.settings.fileClassExcludedFolders = []; plugin.settings.settingsVersion = "5.0"; await plugin.saveData(plugin.settings); MDM_DEBUG && console.log("Metadata menu settings migrated to version 5"); }; // src/suggester/metadataSuggester.ts var import_obsidian78 = require("obsidian"); var listPrefix = " - "; var ValueSuggest = class extends import_obsidian78.EditorSuggest { constructor(plugin) { super(plugin.app); this.inFrontmatter = false; this.inFullLine = false; this.inSentence = false; this.didSelect = false; this.filterOption = (firstValues, lastValue, option) => { return !firstValues || !(firstValues == null ? void 0 : firstValues.contains(encodeLink(option))) && (!lastValue || !!lastValue && encodeLink(option).includes(lastValue)); }; this.plugin = plugin; this.setInstructions([{ command: "Shift", purpose: "remove space after::" }]); this.scope.register(["Shift"], "Enter", (evt) => { this.suggestions.useSelectedItem(evt); return false; }); } isInFrontmatter(editor, cursor) { let frontmatterEnd = void 0; if (editor.getLine(0) === "---") { for (let i = 1; i <= editor.lastLine(); i++) { if (editor.getLine(i) === "---") { frontmatterEnd = i; break; } } } return !!frontmatterEnd && cursor.line < frontmatterEnd; } onTrigger(cursor, editor, file) { var _a; if (this.didSelect) { this.didSelect = false; return null; } if (!this.plugin.settings.isAutosuggestEnabled) { return null; } ; if ((file == null ? void 0 : file.extension) !== "md") return null; if ((_a = editor.editorComponent) == null ? void 0 : _a.table) return null; const fullLine = editor.getLine(editor.getCursor().line); if (fullLine.startsWith("|")) return null; this.inFrontmatter = this.isInFrontmatter(editor, cursor); if (this.inFrontmatter) { const regex = new RegExp(`^${genericFieldRegex}:(?.*)`, "u"); if (!regex.test(fullLine) && !fullLine.startsWith(listPrefix)) { return null; } else { const line = editor.getLine(cursor.line); const separatorPos = line.indexOf(":"); if (!["", " "].includes(line.slice(separatorPos + 1, separatorPos + 2))) { editor.replaceRange(" ", { line: cursor.line, ch: separatorPos + 1 }, { line: cursor.line, ch: separatorPos + 1 }); } } ; } else if (getLineFields(fullLine).length === 0) { return null; } return { start: cursor, end: cursor, query: editor.getLine(cursor.line) }; } getAlias(tFile) { var _a, _b; const dvApi = (_a = this.plugin.app.plugins.plugins.dataview) == null ? void 0 : _a.api; let alias = void 0; if (dvApi && ((_b = this.field) == null ? void 0 : _b.options.customRendering)) { alias = new Function("page", `return ${this.field.options.customRendering}`)(dvApi.page(tFile.path)); } return alias; } async getSuggestions(context) { const suggestions = await this.getValueSuggestions(context); if (suggestions.length) { return suggestions; } return []; } async getValueSuggestions(context) { var _a, _b, _c, _d; const lineNumber = context.start.line; const matchField = { attribute: void 0, values: [] }; const dvApi = (_a = this.plugin.app.plugins.plugins.dataview) == null ? void 0 : _a.api; const file = (_b = this.context) == null ? void 0 : _b.file; if (!file) return []; const splitValues = (values) => { return (values == null ? void 0 : values.replace(/^\[|^\s\[|^\(|^\s\(/, "").replace(/\]$|\)$/, "").split(",").map((o) => encodeLink(o.trim()))) || [""]; }; const getFilteredOptionsList = (field2, firstValues, lastValue) => { const fieldVM = fieldValueManager(this.plugin, field2.id, field2.fileClassName, file); if (!fieldVM || !["Cycle", "Multi", "Select"].includes(fieldVM.type)) return []; const options2 = getOptionsList(fieldVM); return options2.filter((option) => { return this.filterOption(firstValues, lastValue, option); }).map((_value) => Object({ attr: field2.name, value: _value })); }; if (!this.inFrontmatter) { const lineFields = getLineFields(encodeLink(context.editor.getLine(lineNumber))); const position = context.editor.getCursor().ch; const activeLineField = lineFields.find((lineField) => lineField.index <= position && lineField.index + lineField.length >= position); if (activeLineField) { this.inSentence = activeLineField.index > 0; this.inFullLine = activeLineField.index === 0; matchField.attribute = activeLineField.attribute; matchField.values = splitValues(activeLineField.values); } } else { const fieldRegex = new RegExp(`^${genericFieldRegex}:(?.+)?`, "u"); const listItemRegex = new RegExp(`^${listPrefix}(?.+)?`, "u"); let fieldLine = lineNumber; while (!context.editor.getLine(fieldLine).includes(":") && fieldLine > 0) fieldLine = fieldLine - 1; const regexResult = context.editor.getRange({ line: fieldLine, ch: 0 }, context.end).match(fieldRegex); if (regexResult == null ? void 0 : regexResult.groups) { matchField.attribute = regexResult.groups.attribute; matchField.values = splitValues(regexResult.groups.values); } let i = 1; while (context.editor.getLine(fieldLine + i).startsWith(listPrefix) && fieldLine + i <= context.editor.lastLine()) { const regexResult2 = context.editor.getLine(fieldLine + i).match(listItemRegex); if (regexResult2 == null ? void 0 : regexResult2.groups) (_c = matchField.values) == null ? void 0 : _c.push(...splitValues(regexResult2.groups.values)); i += 1; } } ; if (matchField.attribute) { const fieldName = matchField.attribute; this.field = (_d = this.plugin.fieldIndex.filesFields.get(context.file.path)) == null ? void 0 : _d.find((f) => f.name === fieldName); const valuesList = matchField.values; const lastValue = valuesList == null ? void 0 : valuesList.last(); const firstValues = valuesList == null ? void 0 : valuesList.slice(0, -1); if (fieldName === "tags" && this.inFrontmatter) { return Object.keys(this.plugin.app.metadataCache.getTags()).filter((t) => lastValue ? t.contains(lastValue) : t).sort().map((tag) => Object({ attr: fieldName, value: tag.replace(/^#/, "") })); } if (this.field && ["Cycle", "Multi", "Select"].includes(this.field.type)) { return getFilteredOptionsList(this.field, firstValues, lastValue); } else if (this.field && ["File", "MultiFile"].includes(this.field.type)) { const sortingMethod = new Function("a", "b", `return ${this.field.options.customSorting}`) || function(a, b) { return a.basename < b.basename ? -1 : 1; }; const fieldVM = fieldValueManager(this.plugin, this.field.id, this.field.fileClassName, file); const files = getFiles(fieldVM); if (lastValue) { const results = files.filter((f) => { var _a2; return f.basename.toLowerCase().includes(lastValue.toLowerCase()) || ((_a2 = this.getAlias(f)) == null ? void 0 : _a2.toLowerCase().includes(lastValue.toLowerCase())); }).map((f) => { return Object({ attr: fieldName, value: buildMarkDownLink(this.plugin, context.file, f.basename, void 0, this.getAlias(f)) }); }); return results; } else { return files.map((f) => { var _a2; let alias = void 0; if (dvApi && ((_a2 = this.field) == null ? void 0 : _a2.options.customRendering)) { alias = new Function("page", `return ${this.field.options.customRendering}`)(dvApi.page(f.path)); } return Object({ attr: fieldName, value: buildMarkDownLink(this.plugin, context.file, f.basename, void 0, alias) }); }); } } else { return []; } } ; return []; } renderSuggestion(suggestion, el) { var _a; el.addClass("metadata-menu"); el.addClass("suggester"); const [rawValue, alias] = `${suggestion.value}`.replace(/^\[\[/, "").replace(/\]\]$/, "").split("|"); const targetFile = this.plugin.app.metadataCache.getFirstLinkpathDest(rawValue, this.context.file.path); const dvApi = (_a = this.plugin.app.plugins.plugins.dataview) == null ? void 0 : _a.api; if (dvApi && this.field && this.field.options.customRendering && targetFile) { if (alias) { const suggestionContainer = el.createDiv({ cls: "item-with-alias" }); suggestionContainer.createDiv({ text: alias }); const filePath = suggestionContainer.createDiv({ cls: "item-with-alias-filepath" }); filePath.setText(rawValue); } else { el.setText(new Function("page", `return ${this.field.options.customRendering}`)(dvApi.page(targetFile.path))); } } else { el.setText(rawValue); } } getFieldLines(editor, fieldName) { let beginFieldLineNumber = this.context.start.line; let endFieldLineNumber = this.context.start.line; while (!editor.getLine(beginFieldLineNumber).startsWith(`${fieldName}:`) && beginFieldLineNumber > 0) beginFieldLineNumber = beginFieldLineNumber - 1; while (!editor.getLine(endFieldLineNumber + 1).includes(":") && !(editor.getLine(endFieldLineNumber + 1) === "---") && endFieldLineNumber + 1 <= this.context.editor.lastLine()) endFieldLineNumber = endFieldLineNumber + 1; return { beginFieldLineNumber, endFieldLineNumber }; } async selectSuggestion(suggestion, event) { var _a, _b, _c, _d; const activeView = this.plugin.app.workspace.getActiveViewOfType(import_obsidian78.MarkdownView); if (!activeView) { return; } ; const editor = activeView.editor; const activeLine = editor.getLine(this.context.start.line); const file = (_a = this.context) == null ? void 0 : _a.file; if (!(file instanceof import_obsidian78.TFile)) return; const position = ((_b = this.context) == null ? void 0 : _b.editor.getCursor().ch) || 0; const fieldName = suggestion.attr; if (this.inFrontmatter && fieldName === "tags") { const clean = (item) => { return item == null ? void 0 : item.replace(/\s?\,$/, ""); }; try { const { beginFieldLineNumber, endFieldLineNumber } = this.getFieldLines(editor, fieldName); const serializedField = editor.getRange( { line: beginFieldLineNumber, ch: 0 }, { line: endFieldLineNumber, ch: editor.getLine(endFieldLineNumber).length } ); let parsedField2 = (0, import_obsidian78.parseYaml)(serializedField); let [attr, pastValues] = Object.entries(parsedField2)[0]; let newField; if (this.plugin.settings.frontmatterListDisplay === "asList" /* asList */) { let valuesArray = [suggestion.value]; const options2 = Object.keys(this.plugin.app.metadataCache.getTags()).map((t) => t.replace(/^#/, "")); if (typeof pastValues == "string") { valuesArray = [...new Set([clean(pastValues), ...valuesArray].filter((item) => options2.includes(item)))]; } else if (Array.isArray(pastValues)) { valuesArray = [...new Set([ ...pastValues.filter((v) => !!v).map((value) => clean(value)), ...valuesArray ].filter((item) => options2.includes(item)))]; } newField = `${attr}: ${valuesArray.map((value) => ` - ${clean(value)}`).join("")}`; } else { if (!pastValues) { newField = attr + ": " + suggestion.value; } else if (typeof pastValues == "string") { if (!pastValues.contains(",")) { newField = attr + ": " + suggestion.value; } else { const pastValuesArray = pastValues.split(",").map((o) => o.trim()).slice(0, -1); newField = attr + ": [" + pastValuesArray.join(", ") + ", " + clean(suggestion.value) + "]"; } } else if (Array.isArray(pastValues)) { if (activeLine.endsWith(",]") || activeLine.endsWith(", ]")) { newField = attr + ": [" + [...pastValues, clean(suggestion.value)].join(", ") + "]"; } else { newField = attr + ": [" + [...pastValues.slice(0, -1), clean(suggestion.value)].join(", ") + "]"; } } else { newField = attr + ": [" + [...pastValues].join(", ") + "]"; } } editor.replaceRange(newField, { line: beginFieldLineNumber, ch: 0 }, { line: endFieldLineNumber, ch: editor.getLine(endFieldLineNumber).length }); if (this.plugin.settings.frontmatterListDisplay === "asList" /* asList */) { let endFieldLineNumber2 = this.context.start.line; while (!editor.getLine(endFieldLineNumber2 + 1).includes(":") && !(editor.getLine(endFieldLineNumber2 + 1) === "---")) { editor.getLine(endFieldLineNumber2); endFieldLineNumber2 = endFieldLineNumber2 + 1; } editor.setCursor({ line: endFieldLineNumber2, ch: editor.getLine(endFieldLineNumber2).length }); } } catch (error) { new import_obsidian78.Notice("incorrect frontmatter format", 2e3); this.close(); return; } } else { const note = await Note.buildNote(this.plugin, file); const eF = note.existingFields.find((eF2) => eF2.field.isRoot() && eF2.field.name === fieldName); if (!(eF == null ? void 0 : eF.indexedPath)) return; const currentValue = Array.isArray(eF.value) ? eF.value : !eF.value ? [] : [eF.value]; if (this.inFrontmatter) { const { beginFieldLineNumber, endFieldLineNumber } = this.getFieldLines(editor, fieldName); const renderedValue = note.renderFieldValue(eF.field, [...currentValue, suggestion.value].join(","), this.inFrontmatter ? "yaml" : "inline"); const newField = Array.isArray(renderedValue) && ((_c = this.field) == null ? void 0 : _c.getDisplay()) === "asArray" /* asArray */ ? `${fieldName}: [${renderedValue.join(", ")}]` : Array.isArray(renderedValue) ? `${fieldName}: ${renderedValue.map((v) => " - " + v).join("\n")}` : `${fieldName}: ${renderedValue}`; editor.replaceRange(newField, { line: beginFieldLineNumber, ch: 0 }, { line: endFieldLineNumber, ch: editor.getLine(endFieldLineNumber).length }); if (!(((_d = this.field) == null ? void 0 : _d.getDisplay()) === "asList" /* asList */) && !(fieldName === "tags" && this.plugin.settings.frontmatterListDisplay === "asList" /* asList */)) { editor.setCursor({ line: beginFieldLineNumber, ch: newField.length - 1 }); } else { let endFieldLineNumber2 = this.context.start.line; while (!editor.getLine(endFieldLineNumber2 + 1).includes(":") && !(editor.getLine(endFieldLineNumber2 + 1) === "---")) { editor.getLine(endFieldLineNumber2); endFieldLineNumber2 = endFieldLineNumber2 + 1; } editor.setCursor({ line: endFieldLineNumber2, ch: editor.getLine(endFieldLineNumber2).length }); } } else if (this.inFullLine && this.field) { let cleanedLine = activeLine; while (![",", ":"].contains(cleanedLine.charAt(cleanedLine.length - 1))) { cleanedLine = cleanedLine.slice(0, -1); } editor.replaceRange( `${cleanedLine}${event.shiftKey ? "" : " "}` + suggestion.value, { line: this.context.start.line, ch: 0 }, this.context.end ); } else if (this.inSentence && this.field) { let beforeCursor = activeLine.slice(0, position); let afterCursor = activeLine.slice(position); let separatorPos = position; let currentValueLength = 0; while (!beforeCursor.endsWith("::") && !beforeCursor.endsWith(",") && beforeCursor.length) { separatorPos = separatorPos - 1; currentValueLength = currentValueLength + 1; beforeCursor = beforeCursor.slice(0, -1); } let nextBracketPos = position; while (!encodeLink(afterCursor).match("(\\]|\\)).*") && afterCursor.length) { nextBracketPos = nextBracketPos + 1; afterCursor = afterCursor.slice(nextBracketPos - position); } editor.replaceRange( suggestion.value, { line: this.context.start.line, ch: separatorPos }, { line: this.context.start.line, ch: nextBracketPos } ); editor.setCursor({ line: this.context.start.line, ch: nextBracketPos - currentValueLength + suggestion.value.length }); } } this.didSelect = true; this.close(); } }; // src/options/updateProps.ts var import_obsidian79 = require("obsidian"); var import_promises6 = require("timers/promises"); function isPropView(view) { return view.file !== void 0; } var updateProps = async (plugin, view, file) => { const optionsList = new OptionsList(plugin, file, "ManageAtCursorCommand"); const note = new Note(plugin, file); await note.build(); view.metadataEditor.rendered.forEach((item) => { var _a, _b, _c, _d; const key = item.entry.key; const pseudoField = { id: key === plugin.settings.fileClassAlias ? `fileclass-field-${plugin.settings.fileClassAlias}` : (_b = (_a = plugin.fieldIndex.filesFields.get(file.path)) == null ? void 0 : _a.find((_f) => _f.isRoot() && _f.name === key)) == null ? void 0 : _b.id, type: key === plugin.settings.fileClassAlias ? "Select" : (_d = (_c = plugin.fieldIndex.filesFields.get(file.path)) == null ? void 0 : _c.find((_f) => _f.isRoot() && _f.name === key)) == null ? void 0 : _d.type }; if (!pseudoField.id || !pseudoField.type) return; const node = note.getNodeForIndexedPath(pseudoField.id); if (!node) return; const buttonsContainers = item.containerEl.findAll(".field-btn-container"); buttonsContainers.forEach((container) => item.containerEl.removeChild(container)); const btnContainer = item.containerEl.createDiv({ cls: "field-btn-container" }); if (isPropView(view)) btnContainer.addClass("with-bottom-border"); const btn = new import_obsidian79.ButtonComponent(btnContainer); btn.setIcon(getIcon(pseudoField.type)); btn.setClass("property-metadata-menu"); btn.onClick(() => { optionsList ? optionsList.createAndOpenNodeFieldModal(node) : null; }); item.containerEl.insertBefore(btnContainer, item.valueEl); }); const actionContainer = view.metadataEditor.contentEl.find(".action-container") || view.metadataEditor.contentEl.createDiv({ cls: "action-container" }); actionContainer.replaceChildren(); actionContainer.appendChild(view.metadataEditor.addPropertyButtonEl); const fileClassButtonsContainer = view.metadataEditor.contentEl.find(".fileclass-btn-container") || view.metadataEditor.contentEl.createDiv({ cls: "fileclass-btn-container" }); fileClassButtonsContainer.replaceChildren(); const fileClasses = plugin.fieldIndex.filesFileClasses.get(file.path); fileClasses == null ? void 0 : fileClasses.forEach((fileClass) => { const addFieldButton = new import_obsidian79.ButtonComponent(fileClassButtonsContainer); addFieldButton.setClass("add-field-button"); addFieldButton.setIcon(fileClass.getIcon()); addFieldButton.onClick(() => new InsertFieldSuggestModal(plugin, file, -1, false, false).open()); }); actionContainer.appendChild(fileClassButtonsContainer); }; async function updatePropertiesSection(plugin) { var _a, _b, _c; const leaves = plugin.app.workspace.getLeavesOfType("markdown"); for (const leaf of leaves) { const view = leaf.view; if (!(view instanceof import_obsidian79.MarkdownView) || !(view.file instanceof import_obsidian79.TFile) || view.file === void 0) return; const file = view.file; if (!plugin.app.vault.getAbstractFileByPath(file.path)) continue; updateProps(plugin, view, file); } const currentView = plugin.app.workspace.getActiveViewOfType(import_obsidian79.MarkdownView); if (currentView && currentView.file) { const file = currentView.file; const note = new Note(plugin, file); await note.build(); plugin.indexStatus.checkForUpdate(currentView); const focusedElement = document.querySelector(".metadata-property:focus-within"); if (focusedElement instanceof HTMLElement) { const key = focusedElement.dataset.propertyKey; const field2 = key && ((_a = plugin.fieldIndex.filesFields.get(currentView.file.path)) == null ? void 0 : _a.find((_f) => _f.isRoot() && _f.name === key)); if (field2) { const eF = note.getExistingFieldForIndexedPath(field2.id); (_b = focusedElement.find("[class^=metadata-input]")) == null ? void 0 : _b.setText((eF == null ? void 0 : eF.value) || ""); } else if (key === plugin.settings.fileClassAlias) { const eF = note.getExistingFieldForIndexedPath(`fileclass-field-${plugin.settings.fileClassAlias}`); (_c = focusedElement.find("[class^=metadata-input]")) == null ? void 0 : _c.setText((eF == null ? void 0 : eF.value) || ""); } } } } function getPropView(plugin) { var propView; plugin.app.workspace.iterateAllLeaves((l) => { var _a; if (!propView && l.view.file && ((_a = l.view.plugin) == null ? void 0 : _a.id) === "properties") { propView = l.view; } }); return propView; } async function updatePropertiesPane2(plugin) { var _a; var propView; if (propView && propView.file.path == ((_a = plugin.app.workspace.getActiveFile()) == null ? void 0 : _a.path)) { updateProps(plugin, propView, propView.file); } else { await (0, import_promises6.setTimeout)(300); propView = getPropView(plugin); if (propView) { updateProps(plugin, propView, propView.file); } } } async function updatePropertiesCommands(plugin) { if (plugin.settings.enableProperties) { updatePropertiesSection(plugin); updatePropertiesPane2(plugin); } } // src/fileClass/fileClassFolderButton.ts var import_obsidian80 = require("obsidian"); var FileClassFolderButton = class extends import_obsidian80.Component { constructor(plugin) { super(); this.plugin = plugin; this.addButton(); } onload() { this.registerEvent( this.plugin.app.workspace.on("layout-change", () => { this.addButton(); }) ); this.registerEvent( this.plugin.app.metadataCache.on("metadata-menu:indexed", () => { this.addButton(); }) ); } addButton() { var _a, _b, _c, _d; const fCFolderPath = (_a = this.plugin.settings.classFilesPath) == null ? void 0 : _a.replace(/\/$/, ""); const explorerView = (_c = (_b = this.plugin.app.workspace.getLeavesOfType("file-explorer")) == null ? void 0 : _b[0]) == null ? void 0 : _c.view; if (!explorerView || !fCFolderPath) return; const fCFolder = (_d = explorerView == null ? void 0 : explorerView.fileItems) == null ? void 0 : _d[fCFolderPath]; if (!fCFolder) return; const container = fCFolder.selfEl; const existingButtons = container.findAll(".fileClass-add-button"); for (const btn of existingButtons) container.removeChild(btn); if (!container.findAll(".fileClass-add-button").length) { const addBtn = container.createDiv({ cls: "fileClass-add-button" }); (0, import_obsidian80.setIcon)(addBtn, "plus-circle"); addBtn.onclick = (e) => { e.preventDefault(); new AddNewFileClassModal(this.plugin).open(); }; } } static removeBtn(plugin) { var _a, _b, _c; const fCFolderPath = (_a = plugin.settings.classFilesPath) == null ? void 0 : _a.replace(/\/$/, ""); const explorerView = (_c = (_b = plugin.app.workspace.getLeavesOfType("file-explorer")) == null ? void 0 : _b[0]) == null ? void 0 : _c.view; if (!explorerView || !fCFolderPath) return; const fCFolder = explorerView.fileItems[fCFolderPath]; if (!fCFolder) return; const container = fCFolder.selfEl; const existingButtons = container.findAll(".fileClass-add-button"); for (const btn of existingButtons) container.removeChild(btn); } }; // src/db/DatabaseManager.ts var import_obsidian82 = require("obsidian"); // src/db/StoreManager.ts var import_obsidian81 = require("obsidian"); var StoreManager = class extends import_obsidian81.Component { constructor(indexDB, storeName) { super(); this.indexDB = indexDB; this.storeName = storeName; this.executeRequest = (func) => { const open = indexedDB.open(this.indexDB.name); return new Promise(async (resolve, reject) => { open.onsuccess = () => { const db = open.result; if ([...db.objectStoreNames].find((name) => name === this.storeName)) { const transaction = db.transaction(this.storeName, "readwrite"); const store = transaction.objectStore(this.storeName); resolve(func(store)); } else { MDM_DEBUG && console.error("store not found"); reject(); } }; open.onerror = () => { MDM_DEBUG && console.error("unable to open db"); reject(); }; }); }; this.getElement = (key) => this.executeRequest( (store) => new Promise((resolve, reject) => { let request; if (key === "all") request = store.getAll(); else request = store.get(key); request.onerror = () => reject(request.error); request.onsuccess = () => resolve(request.result); }) ); this.editElement = (key, payload) => this.executeRequest( (store) => new Promise((resolve, reject) => { let request; if (key === "all") request = store.getAll(); else request = store.get(key); request.onerror = () => reject(request.error); request.onsuccess = () => { const serialized = JSON.parse(JSON.stringify(payload)); const updateRequest = store.put(serialized); updateRequest.onsuccess = () => resolve(request.result); }; }) ); this.bulkEditElements = (payload) => this.executeRequest( (store) => new Promise((resolve, reject) => { let request; if (payload.length) { payload.forEach((item) => { request = store.get(item.id); request.onerror = () => { MDM_DEBUG && console.log("error on getting ", item.id); reject(request.error); }; request.onsuccess = () => { const serialized = JSON.parse(JSON.stringify(item)); const updateRequest = store.put(serialized); updateRequest.onsuccess = () => resolve(request.result); }; }); } else { resolve(); } }) ); this.removeElement = (key) => this.executeRequest( (store) => new Promise((resolve, reject) => { let request; if (key === "all") request = store.clear(); else request = store.delete(key); request.onerror = () => reject(request.error); request.onsuccess = () => resolve(); }) ); this.bulkRemoveElements = (keys) => this.executeRequest( (store) => new Promise((resolve, reject) => { let request; if (keys.length) { keys.forEach((key) => { request = store.get(key); request.onerror = () => reject(request.error); request.onsuccess = () => { const delRequest = store.delete(key); delRequest.onsuccess = () => resolve(); }; }); } else { resolve(); } }) ); } }; // src/db/stores/fileClassViews.ts var FileClassViewStore = class extends StoreManager { constructor(indexDB) { super(indexDB, "fileClassView"); this.indexDB = indexDB; } }; // src/db/DatabaseManager.ts var INDEXES = { fileClassView: [ { name: "fileClassView", fields: "fileClassName", unique: true } ] }; var IndexDatabase = class extends import_obsidian82.Component { constructor(plugin) { super(); this.plugin = plugin; this.init(); this.buildStores(); } onload() { } init() { MDM_DEBUG && console.log("create or open db"); this.name = `metadata_menu_${this.plugin.app.appId || this.plugin.app.vault.adapter.basePath || this.plugin.app.vault.getName()}`; if (!this.name) return; const request = indexedDB.open(this.name, 2); request.onerror = (err) => { console.error(`IndexedDB error: ${request.error}`, err); }; request.onsuccess = () => { const db = request.result; }; request.onupgradeneeded = () => { const db = request.result; Object.keys(INDEXES).forEach((storeName) => { const storeIndexes = INDEXES[storeName]; const store = db.createObjectStore(storeName, { keyPath: "id" }); const indexes = [{ name: "id", fields: "id", unique: true }, ...storeIndexes]; indexes.forEach((index) => store.createIndex(index.name, index.fields, { unique: index.unique })); }); }; } buildStores() { this.fileClassViews = this.addChild(new FileClassViewStore(this)); } onunload() { } }; // src/components/FileClassCodeBlockManager.ts var import_obsidian83 = require("obsidian"); // src/fileClass/views/fileClassCodeBlockView.ts var FileClassCodeBlockView = class { constructor(manager, tableId, fileClass, paginationContainer, tableContainer, selectedView, ctx, children = []) { this.manager = manager; this.tableId = tableId; this.fileClass = fileClass; this.paginationContainer = paginationContainer; this.tableContainer = tableContainer; this.selectedView = selectedView; this.ctx = ctx; this.children = children; this.plugin = this.manager.plugin; this.viewConfiguration = this.getViewConfig(); this.fileClassDataviewTable = new FileClassDataviewTable(this.viewConfiguration, this, fileClass); } getViewConfig() { var _a; const options2 = this.fileClass.getFileClassOptions(); const columns = [{ id: "file", name: "file", hidden: false, position: 0 }]; const sortedFields = getSortedRootFields(this.plugin, this.fileClass); for (const [_index, f] of sortedFields.entries()) { columns.push({ id: `${this.fileClass.name}____${f.name}`, name: f.name, hidden: false, position: _index + 1 }); } const defaultConfig = { children: [], filters: [], sorters: [], columns }; const partialViewConfig = ((_a = options2.savedViews) == null ? void 0 : _a.find((view) => view.name === this.selectedView)) || defaultConfig; return { children: partialViewConfig.children || [], filters: partialViewConfig.filters, sorters: partialViewConfig.sorters, columns: partialViewConfig.columns }; } update(maxRows, sliceStart = 0) { this.fileClassDataviewTable = new FileClassDataviewTable( this.viewConfiguration, this, this.fileClass, maxRows, sliceStart, this.ctx ); this.fileClassDataviewTable.buildPaginationManager(this.paginationContainer); this.fileClassDataviewTable.buildTable(this.tableContainer); } }; // src/components/FileClassCodeBlockManager.ts var FileClassCodeBlockManager = class extends import_obsidian83.MarkdownRenderChild { constructor(plugin, containerEl, source, ctx) { super(containerEl); this.plugin = plugin; this.containerEl = containerEl; this.source = source; this.ctx = ctx; this.isLoaded = false; this.showAddField = false; } build() { var _a; const el = this.containerEl; const source = this.source; el.replaceChildren(); el.addClass("metadata-menu"); el.addClass("fileclass-codeblock-view"); const container = el.createDiv({ cls: "fv-table" }); const header = container.createDiv({ cls: "options" }); const paginationContainer = header.createDiv({ cls: "pagination" }); this.tableId = `table-container-${Math.floor(Date.now())}`; const tableContainer = container.createDiv({ attr: { id: this.tableId } }); container.createDiv(); try { const content = (0, import_obsidian83.parseYaml)(source); const fileClassName = content[this.plugin.settings.fileClassAlias]; const selectedView = (_a = content.view) == null ? void 0 : _a.toString(); this.fileClass = this.plugin.fieldIndex.fileClassesName.get(fileClassName); if (this.fileClass) { this.itemsPerPage = content["files per page"] || this.fileClass.options.limit || this.plugin.settings.tableViewMaxRecords; this.startAtItem = content["start"] || 0; this.showAddField = content["showAddField"] === true || false; this.fileClassCodeBlockView = new FileClassCodeBlockView(this, this.tableId, this.fileClass, paginationContainer, tableContainer, selectedView, this.ctx); this.fileClassCodeBlockView.fileClassDataviewTable.limit = this.itemsPerPage; this.plugin.registerMarkdownPostProcessor((el2, ctx) => { this.fileClassCodeBlockView.fileClassDataviewTable.buidFileClassViewBtn(); }); this.fileClassCodeBlockView.update(this.itemsPerPage, this.startAtItem); this.isLoaded = true; } else { el.setText(`${fileClassName} isn't a proper fileclass`); } } catch (e) { el.setText(e); } } onload() { this.build(); } onunload() { this.plugin.codeBlockListManager.removeChild(this); } }; // src/components/FileClassCodeBlockListManager.ts var import_obsidian84 = require("obsidian"); var FileClassCodeBlockListManager = class extends import_obsidian84.Component { constructor(plugin) { super(); } }; // main.ts var MetadataMenu = class extends import_obsidian85.Plugin { constructor() { super(...arguments); this.presetFields = []; this.initialFileClassQueries = []; this.launched = false; } async onload() { console.log("+------ Metadata Menu loaded ------x-+"); this.register(() => delete window.MDM_DEBUG); this.indexName = `metadata_menu_${this.app.appId || this.app.vault.adapter.basePath || this.app.vault.getName()}`; (window["MetadataMenuAPI"] = this.api) && this.register(() => delete window["MetadataMenuAPI"]); (window["MetadataMenu"] = this) && this.register(() => delete window["MetadataMenu"]); if (!this.app.plugins.enabledPlugins.has("dataview") || //@ts-ignore this.app.plugins.plugins["dataview"] && !this.app.plugins.plugins["dataview"].settings.enableDataviewJs) { new import_obsidian85.Notice( `------------------------------------------ (!) INFO (!) Install and enable dataview and dataviewJS for extra Metadata Menu features ------------------------------------------`, 6e4 ); } await this.loadSettings(); await migrateSettings(this); this.indexStatus = this.addChild(new IndexStatus(this)); this.codeBlockListManager = this.addChild(new FileClassCodeBlockListManager(this)); this.fieldIndex = this.addChild(new FieldIndex(this)); this.contextMenu = this.addChild(new ContextMenu(this)); this.settings.presetFields.forEach((prop) => { const property = new (buildEmptyField(this, void 0))(); Object.assign(property, prop); this.presetFields.push(property); }); this.settings.fileClassQueries.forEach((query) => { const fileClassQuery = new FileClassQuery_default(); Object.assign(fileClassQuery, query); this.initialFileClassQueries.push(fileClassQuery); }); this.addSettingTab(new MetadataMenuSettingTab(this)); this.api = new MetadataMenuApi(this).make(); this.registerEvent( this.app.vault.on("create", (file) => { if (!this.fieldIndex.fileClassesName.size) return; if (file instanceof import_obsidian85.TFile && file.extension === "md" && this.settings.chooseFileClassAtFileCreation) { const modal = new AddFileClassToFileModal(this, file); modal.open(); } }) ); this.registerEvent( this.app.workspace.on("active-leaf-change", (leaf) => { if (leaf) this.indexStatus.checkForUpdate(leaf.view); updatePropertiesCommands(this); }) ); this.registerEvent( this.app.workspace.on("file-open", (file) => { updatePropertiesCommands(this); }) ); this.registerEvent( this.app.metadataCache.on("metadata-menu:indexed", () => { this.indexStatus.setState("indexed"); const currentView = this.app.workspace.getActiveViewOfType(import_obsidian85.MarkdownView); if (currentView) this.indexStatus.checkForUpdate(currentView); updatePropertiesCommands(this); FileClassViewManager.reloadViews(this); }) ); this.indexDB = this.addChild(new IndexDatabase(this)); await this.fieldIndex.fullIndex(); this.extraButton = this.addChild(new ExtraButton(this)); if (this.settings.enableFileExplorer) this.addChild(new FileClassFolderButton(this)); this.registerEditorSuggest(new ValueSuggest(this)); this.launched = true; addCommands(this); this.registerMarkdownCodeBlockProcessor("mdm", async (source, el, ctx) => { const fileClassCodeBlockManager = new FileClassCodeBlockManager(this, el, source, ctx); this.codeBlockListManager.addChild(fileClassCodeBlockManager); ctx.addChild(fileClassCodeBlockManager); }); this.app.workspace.trigger("layout-change"); this.testRunner = this.addChild(new TestRunner(this)); if (MDM_DEBUG && this.app.vault.getName() === "test-vault-mdm") { MDM_DEBUG = false; await this.testRunner.run(); } } /* ------------ Settings ------------ */ async loadSettings() { this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); } async saveSettings() { this.settings.presetFields = this.presetFields.map((_field) => { const { plugin, ...field2 } = _field; return field2; }); this.settings.fileClassQueries = this.initialFileClassQueries; await this.saveData(this.settings); await this.fieldIndex.fullIndex(); } onunload() { console.log("x------ Metadata Menu unloaded ------x"); FileClassFolderButton.removeBtn(this); } }; /* nosourcemap */