/*
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 <function using "page">; }`,
  "CustomBulletList": `function(page) { return <function using "page">; }`,
  "CustomSummarizing": `function(page) { return <function using "page">; }`
};
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 = "(?<inQuote>>*(\\s+)?)?(?<inList>- )?(?<preSpacer>(\\s+)?)?(?<startStyle>[_\\*~`]*)(?<attribute>[-\\w\\p{Letter}\\p{Emoji_Presentation}\\s]*)(?<endStyle>[_\\*~`]*)(?<beforeSeparatorSpacer>\\s*)";
var fullLineRegex = new RegExp(`^\\s*${genericFieldRegex}::(?<afterSeparatorSpacer>\\s*)(?<values>.*)?`, "u");
var inSentenceRegexBrackets = new RegExp(`\\[${genericFieldRegex}::(?<afterSeparatorSpacer>\\s*)(?<values>[^\\]]+)?\\]`, "gu");
var inSentenceRegexPar = new RegExp(`\\(${genericFieldRegex}::(?<afterSeparatorSpacer>\\s*)(?<values>[^\\)]+)?\\)`, "gu");
var LinkRegex = new RegExp(`\\[\\[(?<target>[^\\|]*)(\\|)?(?<alias>.*)?\\]\\]`);
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(/(?<indentation>\s*)(?<list>-\s)?(?<attribute>[-\w\p{Letter}\p{Emoji_Presentation}\s\(\)]*[^\s])(?<beforeSeparatorSpacer>\s*):(?<afterSeparatorSpacer>\s*)(?<values>.*)/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 <span class="field-name">${this.managedField.name}</span> 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(`\\{\\{(?<field>[^\\}]+?)\\}\\}`, "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: `<span>Update <b>${field2.name}</b></span>`,
      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, _c;
  attrs.cls = "value-container";
  const editBtn = fieldContainer.createEl("button");
  const fieldValue = dv.el("span", (_a = managedField.value) != null ? _a : "", attrs);
  fieldContainer.appendChild(fieldValue);
  const spacer = fieldContainer.createDiv({ cls: "spacer-1" });
  if ((_b = attrs.options) == null ? void 0 : _b.alwaysOn)
    spacer.hide();
  (0, import_obsidian5.setIcon)(editBtn, getIcon("Number"));
  if (!((_c = attrs == null ? void 0 : attrs.options) == null ? void 0 : _c.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: `<span>Update <b>${name}</b></span>`,
      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 (<dv> 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: `<span>Update <b>${field2.name}</b></span>`,
      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 (<page> object is available)", cls: "sub-text" });
      customRenderingTopContainer.createEl("code", {
        text: `function(page) { return <function using "page">; }`
      });
      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: `<span>Update <b>${field2.name}</b></span>`,
      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: `<span>Cycle <b>${field2.name}</b></span>`,
      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 <span><b>${field2.name}</b></span>`,
      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(`\\{\\{(?<pattern>[^\\}]+?)\\}\\}`, "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: `<span>Update <b>${name}</b></span>`,
      action: dateModalAction,
      icon: dateIconName
    });
    if (fieldVM.options.dateShiftInterval || fieldVM.options.nextShiftIntervalField) {
      location.options.push({
        id: `update_${name}`,
        actionLabel: `<span>Shift <b>${name}</b> ahead</span>`,
        action: shiftDateAction,
        icon: "skip-forward"
      });
    }
    location.options.push({
      id: `clear_${name}`,
      actionLabel: `<span>Clear <b>${name}</b></span>`,
      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) => `<svg xmlns="http://www.w3.org/2000/svg" ${display === "card" ? 'width="164" height="164"' : 'width="40" height="40"'} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-file-question">
    <path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/>
    <polyline points="14 2 14 8 20 8"/>
    <circle cx="10" cy="13" r="2"/><path d="m20 17-1.09-1.09a2 2 0 0 0-2.82 0L10 22"/>
</svg>`;
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 (<dv> 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 = /(?<filePath>.*)__related__(?<fileClassName>.*)___(?<fieldName>.*)/;
    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 = /(?<filePath>.*)__related__(?<fileClassName>.*)___(?<fieldName>.*)/;
    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 = /(?<filePath>.*)__calculated__(?<fileClassName>.*)___(?<fieldName>.*)/;
    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 = /(?<filePath>.*)__calculated__(?<fileClassName>.*)___(?<fieldName>.*)/;
    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: `<span>Update <b>${name}</b></span>`,
        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 = /(?<filePath>.*)__related__(?<fileClassName>.*)___(?<fieldName>.*)/;
    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: `<span>Update <b>${name}</b></span>`,
        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: `<span>Update <b>${field2.name}</b></span>`,
      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))\n+(?!\n|$)", "g");
} catch (e) {
  blockEndNewlines = /\n+(?!\n|$)/g;
}
function blockString({ comment, type, value }, ctx, onComment, onChompKeep) {
  const { blockQuote, commentString, lineWidth } = ctx.options;
  if (!blockQuote || /\n[\t ]+$/.test(value) || /^\s*$/.test(value)) {
    return quotedString(value, ctx);
  }
  const indent = ctx.indent || (ctx.forceBlockIndent || containsDocumentMarker(value) ? "  " : "");
  const literal = blockQuote === "literal" ? true : blockQuote === "folded" || type === Scalar.BLOCK_FOLDED ? false : type === Scalar.BLOCK_LITERAL ? true : !lineLengthOverLimit(value, lineWidth, indent.length);
  if (!value)
    return literal ? "|\n" : ">\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<unknown, unknown>`,
   * 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("(.*?)(?<![ 	])[ 	]*\r?\n", "sy");
    line = new RegExp("[ 	]*(.*?)(?:(?<![ 	])[ 	]*)?\r?\n", "sy");
  } catch (_) {
    first = /(.*?)[ \t]*\r?\n/sy;
    line = /[ \t]*(.*?)[ \t]*\r?\n/sy;
  }
  let match = first.exec(source);
  if (!match)
    return source;
  let res = match[1];
  let sep = " ";
  let pos = first.lastIndex;
  line.lastIndex = pos;
  while (match = line.exec(source)) {
    if (match[1] === "") {
      if (sep === "\n")
        res += sep;
      else
        sep = "\n";
    } else {
      res += sep + match[1];
      sep = " ";
    }
    pos = line.lastIndex;
  }
  const last = /[ \t]*(.*)/sy;
  last.lastIndex = pos;
  match = last.exec(source);
  return res + sep + ((_a = match == null ? void 0 : match[1]) != null ? _a : "");
}
function doubleQuotedValue(source, onError) {
  let res = "";
  for (let i = 1; i < source.length - 1; ++i) {
    const ch = source[i];
    if (ch === "\r" && source[i + 1] === "\n")
      continue;
    if (ch === "\n") {
      const { fold, offset: offset2 } = foldNewline(source, i);
      res += fold;
      i = offset2;
    } else if (ch === "\\") {
      let next = source[++i];
      const cc = escapeCodes[next];
      if (cc)
        res += cc;
      else if (next === "\n") {
        next = source[i + 1];
        while (next === " " || next === "	")
          next = source[++i + 1];
      } else if (next === "\r" && source[i + 1] === "\n") {
        next = source[++i + 1];
        while (next === " " || next === "	")
          next = source[++i + 1];
      } else if (next === "x" || next === "u" || next === "U") {
        const length = { x: 2, u: 4, U: 8 }[next];
        res += parseCharCode(source, i + 1, length, onError);
        i += length;
      } else {
        const raw = source.substr(i - 1, 2);
        onError(i - 1, "BAD_DQ_ESCAPE", `Invalid escape sequence ${raw}`);
        res += raw;
      }
    } else if (ch === " " || ch === "	") {
      const wsStart = i;
      let next = source[i + 1];
      while (next === " " || next === "	")
        next = source[++i + 1];
      if (next !== "\n" && !(next === "\r" && source[i + 2] === "\n"))
        res += i > 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}(?<fileClassName>.*).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,
  disableDataviewPrompt: false
};
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 = `<strong>${this.fileClassQuery.name}</strong>`;
    const fileClassNameContainer = fileClassQueryContainer.createEl("div");
    fileClassNameContainer.innerHTML = `<span>FileClass</span> : ${this.fileClassQuery.fileClassName}`;
    const queryContainer = fileClassQueryContainer.createEl("div");
    queryContainer.innerHTML = `<span>Query</span> : ${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");
    if (!this.app.plugins.enabledPlugins.has("dataview") || this.app.plugins.plugins["dataview"] && //@ts-ignore
    !this.app.plugins.plugins["dataview"].settings.enableDataviewJs) {
      new import_obsidian38.Setting(globalSettings.containerEl).setName("Disable dataview notice").setDesc(
        "Dataview is not installed or enabled. Disable this notice"
      ).addToggle((toggle) => {
        toggle.setValue(this.plugin.settings.disableDataviewPrompt);
        toggle.onChange(async (value) => {
          this.plugin.settings.disableDataviewPrompt = 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}<br/>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<br/>(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 `<span class='column-id' id='${column.id}'/>${hasChildren ? column.id.replace("____", ": ") : column.name}</span>`;
    };
    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: `<span>Map <b>${fileClass.name}</b> with tag of same name</span>`,
          action: mapWithTagAction,
          icon: "hash"
        });
      }
      if (fileClass && missingFields && this.fromFile) {
        this.location.options.push({
          id: `insert_missig_fields_from_${fileClass.name.replace("/", "_")}`,
          actionLabel: `<span>Insert missing fields from <b>${fileClass.name}</b></span>`,
          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: `<span>${attr.name}</span>`,
          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: `<span>Insert an attribute for <b>${this.fileClass.name}</b> fileClass</span>`,
        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: `<span>Manage <b>${fileClass.name}</b> fileClass fields</span>`,
          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: `<span>Open fields modal</span>`,
            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("<empty>");
      } else {
        container.createDiv({ text: `${item.name} :`, cls: "label-container" });
        container.createDiv({ text: "<missing>" });
      }
    }
    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(`\\{\\{(?<pattern>[^\\}]+?)\\}\\}`, "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: `<span>Update <b>${name}</b></span>`,
        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: `<span>Update <b>${name}</b></span>`,
        action: moveToObject,
        icon: iconName
      });
      location.options.push({
        id: `remove_${name}`,
        actionLabel: `<span>Remove this <b>${name}</b> item</span>`,
        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(`\\{\\{(?<pattern>[^\\}]+?)\\}\\}`, "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(/(?<indentation>\s*)(?<list>-\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(/(?<id>[^\[]*)(?:\[(?<index>.*)\])?/)) == 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(/(?<blockquote>\>*)(?<indentation>\s*)(?<list>-\s)?(?<value>.*)/);
      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-(?<fileClassAlias>.*)/);
      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---" : "<empty>");
    } else if (value === void 0) {
      fieldValueContainer.setText("<missing>");
    } 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__(?<fieldId>.*)/);
      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__(?<fieldId>.*)/);
      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": `<svg class="svg-icon sync" xmlns="http://www.w3.org/2000/svg" width="24" height="24" stroke="currentColor" viewBox="0 0 24 24" fill="none">
            <path
                d="M9 20H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v1" />
            <path class="rotating" id="arrow"
                d="M12 10v4h4 m-4 0 1.5-1.5c.9-.9 2.2-1.5 3.5-1.5s2.6.6 3.5 1.5c.4.4.8 1 1 1.5 M22 22v-4h-4 m4 0-1.5 1.5c-.9.9-2.1 1.5-3.5 1.5s-2.6-.6-3.5-1.5c-.4-.4-.8-1-1-1.5" />

            <animateTransform href="#arrow" attributeName="transform" type="rotate" from="0 17 16" to="-180 17 16"
                begin="0s" dur="1s" repeatCount="indefinite" />
        </svg>`,
  "indexed": `<svg class="svg-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" stroke="currentColor" viewBox="0 0 24 24" fill="none">
            <path d="M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z"/>
            <path class="check-mark" d="m9 13 2 2 4-4"/>
        </svg>`,
  "update": `<svg class="svg-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor">
            <path stroke="red" d="M8.42 10.61a2.1 2.1 0 1 1 2.97 2.97L5.95 19 2 20l.99-3.95 5.43-5.44Z"/>
            <path d="M2 11.5V5c0-1.1.9-2 2-2h3.93a2 2 0 0 1 1.66.9l.82 1.2a2 2 0 0 0 1.66.9H20a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-9.5"/>
        </svg>`
};
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) => `(?<inQuote>>*(\\s+)?)?(?<inList>- )?(?<preSpacer>(\\s+)?)?(?<startStyle>[_\\*~\`]*)(?<attribute>${attribute})(?<endStyle>[_\\*~\`]*)(?<beforeSeparatorSpacer>\\s*)::(?<afterSeparatorSpacer>\\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)}(?<values>[^\\]]*)`, "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)}(?<values>[^\\]]+)?\\]`, "gu");
        const inSentenceRegexPar2 = new RegExp(`\\(${inlineFieldRegex(fieldName)}(?<values>[^\\)]+)?\\)`, "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}:(?<values>.*)`, "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}:(?<values>.+)?`, "u");
      const listItemRegex = new RegExp(`^${listPrefix}(?<values>.+)?`, "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)
      continue;
    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"]);
    await this.loadSettings();
    await migrateSettings(this);
    if (!this.settings.disableDataviewPrompt && (!this.app.plugins.enabledPlugins.has("dataview") || this.app.plugins.plugins["dataview"] && //@ts-ignore
    !this.app.plugins.plugins["dataview"].settings.enableDataviewJs)) {
      new import_obsidian85.Notice(
        `------------------------------------------
(!) INFO (!) 
Install and enable dataview and dataviewJS for extra Metadata Menu features
------------------------------------------`,
        6e4
      );
    }
    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));
    this.extraButton = this.addChild(new ExtraButton(this));
    if (this.settings.enableFileExplorer)
      this.addChild(new FileClassFolderButton(this));
    this.app.workspace.onLayoutReady(async () => {
      await this.fieldIndex.fullIndex();
      this.launched = true;
      addCommands(this);
      const leaves = this.app.workspace.getLeavesOfType("markdown");
      leaves.forEach((leaf) => {
        if (leaf.view instanceof import_obsidian85.MarkdownView) {
          this.indexStatus.checkForUpdate(leaf.view);
        }
      });
      this.app.workspace.trigger("layout-change");
      requestAnimationFrame(() => {
        requestAnimationFrame(() => {
          updatePropertiesCommands(this);
        });
      });
    });
    this.registerEditorSuggest(new ValueSuggest(this));
    this.registerMarkdownCodeBlockProcessor("mdm", async (source, el, ctx) => {
      const fileClassCodeBlockManager = new FileClassCodeBlockManager(this, el, source, ctx);
      this.codeBlockListManager.addChild(fileClassCodeBlockManager);
      ctx.addChild(fileClassCodeBlockManager);
    });
    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 */