/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/

"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
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 __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __publicField = (obj, key, value) => {
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
  return value;
};

// src/main.ts
var main_exports = {};
__export(main_exports, {
  default: () => CoreSearchAssistantPlugin
});
module.exports = __toCommonJS(main_exports);

// src/Events.ts
var import_obsidian = require("obsidian");
var EVENT_SEARCH_RESULT_ITEM_DETECTED = "search-result-item-detected";
var EVENT_SORT_ORDER_CHANGED = "sort-order-changed";
var CoreSearchAssistantEvents = class extends import_obsidian.Events {
  trigger(name, ...data) {
    super.trigger(name, ...data);
  }
  on(name, callback, ctx) {
    return super.on(name, callback, ctx);
  }
};

// src/ModeScope.ts
var ModeScope = class {
  constructor() {
    this._depth = 0;
  }
  get inSearchMode() {
    return this._depth > 0;
  }
  get depth() {
    return this._depth;
  }
  push() {
    this._depth++;
  }
  pop() {
    this._depth--;
    if (this.depth < 0) {
      throw "[ERROR in Core Search Assistant] ModeScope.depth < 0";
    }
  }
  reset() {
    this._depth = 0;
  }
};

// src/Setting.ts
var import_obsidian6 = require("obsidian");

// src/ui/HotkeySetter.ts
var import_obsidian5 = require("obsidian");

// node_modules/svelte/src/runtime/internal/utils.js
function noop() {
}
function run(fn) {
  return fn();
}
function blank_object() {
  return /* @__PURE__ */ Object.create(null);
}
function run_all(fns) {
  fns.forEach(run);
}
function is_function(thing) {
  return typeof thing === "function";
}
function safe_not_equal(a, b) {
  return a != a ? b == b : a !== b || a && typeof a === "object" || typeof a === "function";
}
function is_empty(obj) {
  return Object.keys(obj).length === 0;
}
function subscribe(store, ...callbacks) {
  if (store == null) {
    for (const callback of callbacks) {
      callback(void 0);
    }
    return noop;
  }
  const unsub = store.subscribe(...callbacks);
  return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;
}
function component_subscribe(component, store, callback) {
  component.$$.on_destroy.push(subscribe(store, callback));
}

// node_modules/svelte/src/runtime/internal/globals.js
var globals = typeof window !== "undefined" ? window : typeof globalThis !== "undefined" ? globalThis : (
  // @ts-ignore Node typings have this
  global
);

// node_modules/svelte/src/runtime/internal/ResizeObserverSingleton.js
var ResizeObserverSingleton = class _ResizeObserverSingleton {
  /** @param {ResizeObserverOptions} options */
  constructor(options) {
    /**
     * @private
     * @readonly
     * @type {WeakMap<Element, import('./private.js').Listener>}
     */
    __publicField(this, "_listeners", "WeakMap" in globals ? /* @__PURE__ */ new WeakMap() : void 0);
    /**
     * @private
     * @type {ResizeObserver}
     */
    __publicField(this, "_observer");
    /** @type {ResizeObserverOptions} */
    __publicField(this, "options");
    this.options = options;
  }
  /**
   * @param {Element} element
   * @param {import('./private.js').Listener} listener
   * @returns {() => void}
   */
  observe(element2, listener) {
    this._listeners.set(element2, listener);
    this._getObserver().observe(element2, this.options);
    return () => {
      this._listeners.delete(element2);
      this._observer.unobserve(element2);
    };
  }
  /**
   * @private
   */
  _getObserver() {
    return this._observer ?? (this._observer = new ResizeObserver((entries) => {
      for (const entry of entries) {
        _ResizeObserverSingleton.entries.set(entry.target, entry);
        this._listeners.get(entry.target)?.(entry);
      }
    }));
  }
};
ResizeObserverSingleton.entries = "WeakMap" in globals ? /* @__PURE__ */ new WeakMap() : void 0;

// node_modules/svelte/src/runtime/internal/dom.js
var is_hydrating = false;
function start_hydrating() {
  is_hydrating = true;
}
function end_hydrating() {
  is_hydrating = false;
}
function append(target, node) {
  target.appendChild(node);
}
function append_styles(target, style_sheet_id, styles) {
  const append_styles_to = get_root_for_style(target);
  if (!append_styles_to.getElementById(style_sheet_id)) {
    const style = element("style");
    style.id = style_sheet_id;
    style.textContent = styles;
    append_stylesheet(append_styles_to, style);
  }
}
function get_root_for_style(node) {
  if (!node)
    return document;
  const root = node.getRootNode ? node.getRootNode() : node.ownerDocument;
  if (root && /** @type {ShadowRoot} */
  root.host) {
    return (
      /** @type {ShadowRoot} */
      root
    );
  }
  return node.ownerDocument;
}
function append_stylesheet(node, style) {
  append(
    /** @type {Document} */
    node.head || node,
    style
  );
  return style.sheet;
}
function insert(target, node, anchor) {
  target.insertBefore(node, anchor || null);
}
function detach(node) {
  if (node.parentNode) {
    node.parentNode.removeChild(node);
  }
}
function destroy_each(iterations, detaching) {
  for (let i = 0; i < iterations.length; i += 1) {
    if (iterations[i])
      iterations[i].d(detaching);
  }
}
function element(name) {
  return document.createElement(name);
}
function text(data) {
  return document.createTextNode(data);
}
function space() {
  return text(" ");
}
function listen(node, event, handler, options) {
  node.addEventListener(event, handler, options);
  return () => node.removeEventListener(event, handler, options);
}
function attr(node, attribute, value) {
  if (value == null)
    node.removeAttribute(attribute);
  else if (node.getAttribute(attribute) !== value)
    node.setAttribute(attribute, value);
}
function children(element2) {
  return Array.from(element2.childNodes);
}
function set_data(text2, data) {
  data = "" + data;
  if (text2.data === data)
    return;
  text2.data = /** @type {string} */
  data;
}
function toggle_class(element2, name, toggle) {
  element2.classList.toggle(name, !!toggle);
}
function custom_event(type, detail, { bubbles = false, cancelable = false } = {}) {
  return new CustomEvent(type, { detail, bubbles, cancelable });
}
function get_custom_elements_slots(element2) {
  const result = {};
  element2.childNodes.forEach(
    /** @param {Element} node */
    (node) => {
      result[node.slot || "default"] = true;
    }
  );
  return result;
}

// node_modules/svelte/src/runtime/internal/lifecycle.js
var current_component;
function set_current_component(component) {
  current_component = component;
}
function get_current_component() {
  if (!current_component)
    throw new Error("Function called outside component initialization");
  return current_component;
}
function onMount(fn) {
  get_current_component().$$.on_mount.push(fn);
}
function onDestroy(fn) {
  get_current_component().$$.on_destroy.push(fn);
}
function createEventDispatcher() {
  const component = get_current_component();
  return (type, detail, { cancelable = false } = {}) => {
    const callbacks = component.$$.callbacks[type];
    if (callbacks) {
      const event = custom_event(
        /** @type {string} */
        type,
        detail,
        { cancelable }
      );
      callbacks.slice().forEach((fn) => {
        fn.call(component, event);
      });
      return !event.defaultPrevented;
    }
    return true;
  };
}

// node_modules/svelte/src/runtime/internal/scheduler.js
var dirty_components = [];
var binding_callbacks = [];
var render_callbacks = [];
var flush_callbacks = [];
var resolved_promise = /* @__PURE__ */ Promise.resolve();
var update_scheduled = false;
function schedule_update() {
  if (!update_scheduled) {
    update_scheduled = true;
    resolved_promise.then(flush);
  }
}
function add_render_callback(fn) {
  render_callbacks.push(fn);
}
var seen_callbacks = /* @__PURE__ */ new Set();
var flushidx = 0;
function flush() {
  if (flushidx !== 0) {
    return;
  }
  const saved_component = current_component;
  do {
    try {
      while (flushidx < dirty_components.length) {
        const component = dirty_components[flushidx];
        flushidx++;
        set_current_component(component);
        update(component.$$);
      }
    } catch (e) {
      dirty_components.length = 0;
      flushidx = 0;
      throw e;
    }
    set_current_component(null);
    dirty_components.length = 0;
    flushidx = 0;
    while (binding_callbacks.length)
      binding_callbacks.pop()();
    for (let i = 0; i < render_callbacks.length; i += 1) {
      const callback = render_callbacks[i];
      if (!seen_callbacks.has(callback)) {
        seen_callbacks.add(callback);
        callback();
      }
    }
    render_callbacks.length = 0;
  } while (dirty_components.length);
  while (flush_callbacks.length) {
    flush_callbacks.pop()();
  }
  update_scheduled = false;
  seen_callbacks.clear();
  set_current_component(saved_component);
}
function update($$) {
  if ($$.fragment !== null) {
    $$.update();
    run_all($$.before_update);
    const dirty = $$.dirty;
    $$.dirty = [-1];
    $$.fragment && $$.fragment.p($$.ctx, dirty);
    $$.after_update.forEach(add_render_callback);
  }
}
function flush_render_callbacks(fns) {
  const filtered = [];
  const targets = [];
  render_callbacks.forEach((c) => fns.indexOf(c) === -1 ? filtered.push(c) : targets.push(c));
  targets.forEach((c) => c());
  render_callbacks = filtered;
}

// node_modules/svelte/src/runtime/internal/transitions.js
var outroing = /* @__PURE__ */ new Set();
var outros;
function group_outros() {
  outros = {
    r: 0,
    c: [],
    p: outros
    // parent group
  };
}
function check_outros() {
  if (!outros.r) {
    run_all(outros.c);
  }
  outros = outros.p;
}
function transition_in(block, local) {
  if (block && block.i) {
    outroing.delete(block);
    block.i(local);
  }
}
function transition_out(block, local, detach2, callback) {
  if (block && block.o) {
    if (outroing.has(block))
      return;
    outroing.add(block);
    outros.c.push(() => {
      outroing.delete(block);
      if (callback) {
        if (detach2)
          block.d(1);
        callback();
      }
    });
    block.o(local);
  } else if (callback) {
    callback();
  }
}

// node_modules/svelte/src/runtime/internal/each.js
function ensure_array_like(array_like_or_iterator) {
  return array_like_or_iterator?.length !== void 0 ? array_like_or_iterator : Array.from(array_like_or_iterator);
}

// node_modules/svelte/src/shared/boolean_attributes.js
var _boolean_attributes = (
  /** @type {const} */
  [
    "allowfullscreen",
    "allowpaymentrequest",
    "async",
    "autofocus",
    "autoplay",
    "checked",
    "controls",
    "default",
    "defer",
    "disabled",
    "formnovalidate",
    "hidden",
    "inert",
    "ismap",
    "loop",
    "multiple",
    "muted",
    "nomodule",
    "novalidate",
    "open",
    "playsinline",
    "readonly",
    "required",
    "reversed",
    "selected"
  ]
);
var boolean_attributes = /* @__PURE__ */ new Set([..._boolean_attributes]);

// node_modules/svelte/src/runtime/internal/Component.js
function create_component(block) {
  block && block.c();
}
function mount_component(component, target, anchor) {
  const { fragment, after_update } = component.$$;
  fragment && fragment.m(target, anchor);
  add_render_callback(() => {
    const new_on_destroy = component.$$.on_mount.map(run).filter(is_function);
    if (component.$$.on_destroy) {
      component.$$.on_destroy.push(...new_on_destroy);
    } else {
      run_all(new_on_destroy);
    }
    component.$$.on_mount = [];
  });
  after_update.forEach(add_render_callback);
}
function destroy_component(component, detaching) {
  const $$ = component.$$;
  if ($$.fragment !== null) {
    flush_render_callbacks($$.after_update);
    run_all($$.on_destroy);
    $$.fragment && $$.fragment.d(detaching);
    $$.on_destroy = $$.fragment = null;
    $$.ctx = [];
  }
}
function make_dirty(component, i) {
  if (component.$$.dirty[0] === -1) {
    dirty_components.push(component);
    schedule_update();
    component.$$.dirty.fill(0);
  }
  component.$$.dirty[i / 31 | 0] |= 1 << i % 31;
}
function init(component, options, instance8, create_fragment8, not_equal, props, append_styles2 = null, dirty = [-1]) {
  const parent_component = current_component;
  set_current_component(component);
  const $$ = component.$$ = {
    fragment: null,
    ctx: [],
    // state
    props,
    update: noop,
    not_equal,
    bound: blank_object(),
    // lifecycle
    on_mount: [],
    on_destroy: [],
    on_disconnect: [],
    before_update: [],
    after_update: [],
    context: new Map(options.context || (parent_component ? parent_component.$$.context : [])),
    // everything else
    callbacks: blank_object(),
    dirty,
    skip_bound: false,
    root: options.target || parent_component.$$.root
  };
  append_styles2 && append_styles2($$.root);
  let ready = false;
  $$.ctx = instance8 ? instance8(component, options.props || {}, (i, ret, ...rest) => {
    const value = rest.length ? rest[0] : ret;
    if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) {
      if (!$$.skip_bound && $$.bound[i])
        $$.bound[i](value);
      if (ready)
        make_dirty(component, i);
    }
    return ret;
  }) : [];
  $$.update();
  ready = true;
  run_all($$.before_update);
  $$.fragment = create_fragment8 ? create_fragment8($$.ctx) : false;
  if (options.target) {
    if (options.hydrate) {
      start_hydrating();
      const nodes = children(options.target);
      $$.fragment && $$.fragment.l(nodes);
      nodes.forEach(detach);
    } else {
      $$.fragment && $$.fragment.c();
    }
    if (options.intro)
      transition_in(component.$$.fragment);
    mount_component(component, options.target, options.anchor);
    end_hydrating();
    flush();
  }
  set_current_component(parent_component);
}
var SvelteElement;
if (typeof HTMLElement === "function") {
  SvelteElement = class extends HTMLElement {
    constructor($$componentCtor, $$slots, use_shadow_dom) {
      super();
      /** The Svelte component constructor */
      __publicField(this, "$$ctor");
      /** Slots */
      __publicField(this, "$$s");
      /** The Svelte component instance */
      __publicField(this, "$$c");
      /** Whether or not the custom element is connected */
      __publicField(this, "$$cn", false);
      /** Component props data */
      __publicField(this, "$$d", {});
      /** `true` if currently in the process of reflecting component props back to attributes */
      __publicField(this, "$$r", false);
      /** @type {Record<string, CustomElementPropDefinition>} Props definition (name, reflected, type etc) */
      __publicField(this, "$$p_d", {});
      /** @type {Record<string, Function[]>} Event listeners */
      __publicField(this, "$$l", {});
      /** @type {Map<Function, Function>} Event listener unsubscribe functions */
      __publicField(this, "$$l_u", /* @__PURE__ */ new Map());
      this.$$ctor = $$componentCtor;
      this.$$s = $$slots;
      if (use_shadow_dom) {
        this.attachShadow({ mode: "open" });
      }
    }
    addEventListener(type, listener, options) {
      this.$$l[type] = this.$$l[type] || [];
      this.$$l[type].push(listener);
      if (this.$$c) {
        const unsub = this.$$c.$on(type, listener);
        this.$$l_u.set(listener, unsub);
      }
      super.addEventListener(type, listener, options);
    }
    removeEventListener(type, listener, options) {
      super.removeEventListener(type, listener, options);
      if (this.$$c) {
        const unsub = this.$$l_u.get(listener);
        if (unsub) {
          unsub();
          this.$$l_u.delete(listener);
        }
      }
    }
    async connectedCallback() {
      this.$$cn = true;
      if (!this.$$c) {
        let create_slot = function(name) {
          return () => {
            let node;
            const obj = {
              c: function create() {
                node = element("slot");
                if (name !== "default") {
                  attr(node, "name", name);
                }
              },
              /**
               * @param {HTMLElement} target
               * @param {HTMLElement} [anchor]
               */
              m: function mount(target, anchor) {
                insert(target, node, anchor);
              },
              d: function destroy(detaching) {
                if (detaching) {
                  detach(node);
                }
              }
            };
            return obj;
          };
        };
        await Promise.resolve();
        if (!this.$$cn || this.$$c) {
          return;
        }
        const $$slots = {};
        const existing_slots = get_custom_elements_slots(this);
        for (const name of this.$$s) {
          if (name in existing_slots) {
            $$slots[name] = [create_slot(name)];
          }
        }
        for (const attribute of this.attributes) {
          const name = this.$$g_p(attribute.name);
          if (!(name in this.$$d)) {
            this.$$d[name] = get_custom_element_value(name, attribute.value, this.$$p_d, "toProp");
          }
        }
        for (const key in this.$$p_d) {
          if (!(key in this.$$d) && this[key] !== void 0) {
            this.$$d[key] = this[key];
            delete this[key];
          }
        }
        this.$$c = new this.$$ctor({
          target: this.shadowRoot || this,
          props: {
            ...this.$$d,
            $$slots,
            $$scope: {
              ctx: []
            }
          }
        });
        const reflect_attributes = () => {
          this.$$r = true;
          for (const key in this.$$p_d) {
            this.$$d[key] = this.$$c.$$.ctx[this.$$c.$$.props[key]];
            if (this.$$p_d[key].reflect) {
              const attribute_value = get_custom_element_value(
                key,
                this.$$d[key],
                this.$$p_d,
                "toAttribute"
              );
              if (attribute_value == null) {
                this.removeAttribute(this.$$p_d[key].attribute || key);
              } else {
                this.setAttribute(this.$$p_d[key].attribute || key, attribute_value);
              }
            }
          }
          this.$$r = false;
        };
        this.$$c.$$.after_update.push(reflect_attributes);
        reflect_attributes();
        for (const type in this.$$l) {
          for (const listener of this.$$l[type]) {
            const unsub = this.$$c.$on(type, listener);
            this.$$l_u.set(listener, unsub);
          }
        }
        this.$$l = {};
      }
    }
    // We don't need this when working within Svelte code, but for compatibility of people using this outside of Svelte
    // and setting attributes through setAttribute etc, this is helpful
    attributeChangedCallback(attr2, _oldValue, newValue) {
      if (this.$$r)
        return;
      attr2 = this.$$g_p(attr2);
      this.$$d[attr2] = get_custom_element_value(attr2, newValue, this.$$p_d, "toProp");
      this.$$c?.$set({ [attr2]: this.$$d[attr2] });
    }
    disconnectedCallback() {
      this.$$cn = false;
      Promise.resolve().then(() => {
        if (!this.$$cn && this.$$c) {
          this.$$c.$destroy();
          this.$$c = void 0;
        }
      });
    }
    $$g_p(attribute_name) {
      return Object.keys(this.$$p_d).find(
        (key) => this.$$p_d[key].attribute === attribute_name || !this.$$p_d[key].attribute && key.toLowerCase() === attribute_name
      ) || attribute_name;
    }
  };
}
function get_custom_element_value(prop, value, props_definition, transform) {
  const type = props_definition[prop]?.type;
  value = type === "Boolean" && typeof value !== "boolean" ? value != null : value;
  if (!transform || !props_definition[prop]) {
    return value;
  } else if (transform === "toAttribute") {
    switch (type) {
      case "Object":
      case "Array":
        return value == null ? null : JSON.stringify(value);
      case "Boolean":
        return value ? "" : null;
      case "Number":
        return value == null ? null : value;
      default:
        return value;
    }
  } else {
    switch (type) {
      case "Object":
      case "Array":
        return value && JSON.parse(value);
      case "Boolean":
        return value;
      case "Number":
        return value != null ? +value : value;
      default:
        return value;
    }
  }
}
var SvelteComponent = class {
  constructor() {
    /**
     * ### PRIVATE API
     *
     * Do not use, may change at any time
     *
     * @type {any}
     */
    __publicField(this, "$$");
    /**
     * ### PRIVATE API
     *
     * Do not use, may change at any time
     *
     * @type {any}
     */
    __publicField(this, "$$set");
  }
  /** @returns {void} */
  $destroy() {
    destroy_component(this, 1);
    this.$destroy = noop;
  }
  /**
   * @template {Extract<keyof Events, string>} K
   * @param {K} type
   * @param {((e: Events[K]) => void) | null | undefined} callback
   * @returns {() => void}
   */
  $on(type, callback) {
    if (!is_function(callback)) {
      return noop;
    }
    const callbacks = this.$$.callbacks[type] || (this.$$.callbacks[type] = []);
    callbacks.push(callback);
    return () => {
      const index = callbacks.indexOf(callback);
      if (index !== -1)
        callbacks.splice(index, 1);
    };
  }
  /**
   * @param {Partial<Props>} props
   * @returns {void}
   */
  $set(props) {
    if (this.$$set && !is_empty(props)) {
      this.$$.skip_bound = true;
      this.$$set(props);
      this.$$.skip_bound = false;
    }
  }
};

// node_modules/svelte/src/shared/version.js
var PUBLIC_VERSION = "4";

// node_modules/svelte/src/runtime/internal/disclose-version/index.js
if (typeof window !== "undefined")
  (window.__svelte || (window.__svelte = { v: /* @__PURE__ */ new Set() })).v.add(PUBLIC_VERSION);

// src/ui/HotKeyEntry.svelte
var import_obsidian4 = require("obsidian");

// src/ui/HotkeySetting.svelte
var import_obsidian3 = require("obsidian");

// src/utils/Keymap.ts
var import_obsidian2 = require("obsidian");
var CODE_KEY_MAP = {
  Semicolon: ";",
  Quote: "'",
  Comma: ",",
  Period: ".",
  Slash: "/",
  BracketLeft: "[",
  BracketRight: "]",
  BackSlash: "\\",
  Backquote: "`",
  Space: " ",
  Minus: "-",
  Equal: "="
};
for (let i = 0; i < 10; i++) {
  CODE_KEY_MAP[`Digit${i}`] = i.toString();
}
for (let i = 65; i < 91; i++) {
  const char = String.fromCharCode(i);
  const upChar = char.toUpperCase();
  CODE_KEY_MAP[`Key${upChar}`] = char;
}
function convertCodeToKey(code) {
  return CODE_KEY_MAP[code] ?? code;
}
function convertKeyToText(key) {
  switch (key) {
    case "ArrowLeft":
      return "\u2190";
    case "ArrowRight":
      return "\u2192";
    case "ArrowUp":
      return "\u2191";
    case "ArrowDown":
      return "\u2193";
    case "Mod":
      return import_obsidian2.Platform.isMacOS ? "\u2318" : "Ctrl";
    case "Ctrl":
      return import_obsidian2.Platform.isMacOS ? "\u2303" : "Ctrl";
    case "Meta":
      return import_obsidian2.Platform.isMacOS ? "\u2318" : "Win";
    case "Alt":
      return import_obsidian2.Platform.isMacOS ? "\u2325" : "Alt";
    case "Shift":
      return import_obsidian2.Platform.isMacOS ? "\u21E7" : "Shift";
    case " ":
      return "Space";
    case "Enter":
      return "\u21B5";
    default:
      return key.charAt(0).toUpperCase() + key.slice(1);
  }
}
function convertHotkeyToText(hotkey) {
  const parts = [];
  hotkey.modifiers.forEach((mod) => {
    parts.push(convertKeyToText(mod));
  });
  const modifierPart = parts.join(" ");
  const keyPart = convertKeyToText(hotkey.key);
  return ` ${modifierPart} ${keyPart} `;
}
function compileModifiers(modifiers) {
  return modifiers.map((modifier) => {
    return "Mod" === modifier ? import_obsidian2.Platform.isMacOS ? "Meta" : "Ctrl" : modifier;
  }).sort().join(",");
}
function decompileModifiers(modifiersId) {
  const modifiers = [];
  const parts = modifiersId.split(",");
  parts.forEach((s) => {
    if (import_obsidian2.Platform.isMacOS && s === "Meta" || !import_obsidian2.Platform.isMacOS && s === "Ctrl") {
      modifiers.push("Mod");
      return;
    }
    if (s === "Alt" || s === "Shift" || s === "Meta" || s === "Ctrl") {
      modifiers.push(s);
      return;
    }
  });
  return modifiers;
}
function getModifiers(evt) {
  const modifiers = [];
  evt.ctrlKey && modifiers.push("Ctrl");
  evt.metaKey && modifiers.push("Meta");
  evt.altKey && modifiers.push("Alt");
  evt.shiftKey && modifiers.push("Shift");
  return compileModifiers(modifiers);
}
function getHotkey(evt) {
  const modifiers = decompileModifiers(getModifiers(evt));
  const key = convertCodeToKey(evt.code);
  return {
    modifiers,
    key
  };
}
function contain(hotkeys, hotkey) {
  const hotkeyId = convertHotkeyToText(hotkey);
  return hotkeys.some((key) => {
    return hotkeyId === convertHotkeyToText(key);
  });
}

// src/ui/HotkeySetting.svelte
function add_css(target) {
  append_styles(target, "svelte-2wacg2", ".icon-container.svelte-2wacg2{display:inline-block;cursor:pointer;width:16px;height:16px;border-radius:10px;line-height:16px;text-align:center}.icon-container.svelte-2wacg2:hover{background-color:var(--background-modifier-error);color:var(--text-on-accent)}.setting-hotkey.svelte-2wacg2{font-size:12px;background-color:var(--background-secondary-alt);border-radius:4px;padding:0 10px;min-height:24px;align-self:flex-end;position:relative}");
}
function create_fragment(ctx) {
  let span1;
  let t0_value = convertHotkeyToText(
    /*hotkey*/
    ctx[0]
  ) + "";
  let t0;
  let t1;
  let span0;
  let mounted;
  let dispose;
  return {
    c() {
      span1 = element("span");
      t0 = text(t0_value);
      t1 = space();
      span0 = element("span");
      attr(span0, "class", "icon-container svelte-2wacg2");
      attr(span1, "class", "setting-hotkey svelte-2wacg2");
    },
    m(target, anchor) {
      insert(target, span1, anchor);
      append(span1, t0);
      append(span1, t1);
      append(span1, span0);
      ctx[3](span0);
      if (!mounted) {
        dispose = listen(
          span0,
          "click",
          /*onIconClicked*/
          ctx[2]
        );
        mounted = true;
      }
    },
    p(ctx2, [dirty]) {
      if (dirty & /*hotkey*/
      1 && t0_value !== (t0_value = convertHotkeyToText(
        /*hotkey*/
        ctx2[0]
      ) + ""))
        set_data(t0, t0_value);
    },
    i: noop,
    o: noop,
    d(detaching) {
      if (detaching) {
        detach(span1);
      }
      ctx[3](null);
      mounted = false;
      dispose();
    }
  };
}
function instance($$self, $$props, $$invalidate) {
  let { hotkey } = $$props;
  let iconContainerEl;
  const dispatcher = createEventDispatcher();
  onMount(() => {
    if (iconContainerEl instanceof HTMLSpanElement) {
      (0, import_obsidian3.setIcon)(iconContainerEl, "cross", 8);
    }
  });
  function onIconClicked() {
    dispatcher("removed");
  }
  function span0_binding($$value) {
    binding_callbacks[$$value ? "unshift" : "push"](() => {
      iconContainerEl = $$value;
      $$invalidate(1, iconContainerEl);
    });
  }
  $$self.$$set = ($$props2) => {
    if ("hotkey" in $$props2)
      $$invalidate(0, hotkey = $$props2.hotkey);
  };
  return [hotkey, iconContainerEl, onIconClicked, span0_binding];
}
var HotkeySetting = class extends SvelteComponent {
  constructor(options) {
    super();
    init(this, options, instance, create_fragment, safe_not_equal, { hotkey: 0 }, add_css);
  }
};
var HotkeySetting_default = HotkeySetting;

// src/ui/HotKeyEntry.svelte
function add_css2(target) {
  append_styles(target, "svelte-1my40ui", ".item-container.svelte-1my40ui{display:flex;align-items:center;padding:18px 0 18px 0;border-top:1px solid var(--background-modifier-border)}.info-container.svelte-1my40ui{flex:1 1 auto;flex-grow:1;margin-right:20px}.control-container.svelte-1my40ui{flex:1 1 auto;text-align:right;display:flex;justify-content:flex-end;align-items:center}.hotkeys-container.svelte-1my40ui{display:flex;flex-direction:column;margin-right:6px}.setting-hotkey.svelte-1my40ui{font-size:12px;background-color:var(--interactive-accent);border-radius:4px;padding:0 10px;min-height:24px;align-self:flex-end;position:relative;color:var(--text-on-accent)}.icon-container.svelte-1my40ui{padding:4px 6px;border-radius:4px;color:var(--text-faint);cursor:pointer;height:26px}.icon-container.svelte-1my40ui:hover{background-color:var(--background-secondary-alt);color:var(--text-normal)}.icon-container.svelte-1my40ui .clickable-icon{color:unset;cursor:unset;margin:unset}.icon-container.svelte-1my40ui .setting-editor-extra-setting-button{line-height:0}.icon-container.svelte-1my40ui .clickable-icon svg{position:relative;bottom:2px}");
}
function get_each_context(ctx, list, i) {
  const child_ctx = ctx.slice();
  child_ctx[13] = list[i];
  return child_ctx;
}
function create_each_block(ctx) {
  let hotkeysetting;
  let current;
  function removed_handler() {
    return (
      /*removed_handler*/
      ctx[8](
        /*hotkey*/
        ctx[13]
      )
    );
  }
  hotkeysetting = new HotkeySetting_default({ props: { hotkey: (
    /*hotkey*/
    ctx[13]
  ) } });
  hotkeysetting.$on("removed", removed_handler);
  return {
    c() {
      create_component(hotkeysetting.$$.fragment);
    },
    m(target, anchor) {
      mount_component(hotkeysetting, target, anchor);
      current = true;
    },
    p(new_ctx, dirty) {
      ctx = new_ctx;
      const hotkeysetting_changes = {};
      if (dirty & /*_hotkeys*/
      16)
        hotkeysetting_changes.hotkey = /*hotkey*/
        ctx[13];
      hotkeysetting.$set(hotkeysetting_changes);
    },
    i(local) {
      if (current)
        return;
      transition_in(hotkeysetting.$$.fragment, local);
      current = true;
    },
    o(local) {
      transition_out(hotkeysetting.$$.fragment, local);
      current = false;
    },
    d(detaching) {
      destroy_component(hotkeysetting, detaching);
    }
  };
}
function create_if_block(ctx) {
  let div;
  return {
    c() {
      div = element("div");
      div.textContent = "Press hotkey...";
      attr(div, "class", "setting-hotkey svelte-1my40ui");
    },
    m(target, anchor) {
      insert(target, div, anchor);
    },
    d(detaching) {
      if (detaching) {
        detach(div);
      }
    }
  };
}
function create_fragment2(ctx) {
  let div3;
  let div0;
  let t0;
  let t1;
  let div2;
  let div1;
  let t2;
  let t3;
  let span0;
  let t4;
  let span1;
  let current;
  let mounted;
  let dispose;
  let each_value = ensure_array_like(
    /*_hotkeys*/
    ctx[4] ?? []
  );
  let each_blocks = [];
  for (let i = 0; i < each_value.length; i += 1) {
    each_blocks[i] = create_each_block(get_each_context(ctx, each_value, i));
  }
  const out = (i) => transition_out(each_blocks[i], 1, 1, () => {
    each_blocks[i] = null;
  });
  let if_block = (
    /*_listening*/
    ctx[3] && create_if_block(ctx)
  );
  return {
    c() {
      div3 = element("div");
      div0 = element("div");
      t0 = text(
        /*actionName*/
        ctx[0]
      );
      t1 = space();
      div2 = element("div");
      div1 = element("div");
      for (let i = 0; i < each_blocks.length; i += 1) {
        each_blocks[i].c();
      }
      t2 = space();
      if (if_block)
        if_block.c();
      t3 = space();
      span0 = element("span");
      t4 = space();
      span1 = element("span");
      attr(div0, "class", "info-container svelte-1my40ui");
      attr(div1, "class", "hotkeys-container svelte-1my40ui");
      attr(span0, "class", "icon-container svelte-1my40ui");
      attr(span1, "class", "icon-container svelte-1my40ui");
      attr(div2, "class", "control-container svelte-1my40ui");
      attr(div3, "class", "item-container svelte-1my40ui");
    },
    m(target, anchor) {
      insert(target, div3, anchor);
      append(div3, div0);
      append(div0, t0);
      append(div3, t1);
      append(div3, div2);
      append(div2, div1);
      for (let i = 0; i < each_blocks.length; i += 1) {
        if (each_blocks[i]) {
          each_blocks[i].m(div1, null);
        }
      }
      append(div1, t2);
      if (if_block)
        if_block.m(div1, null);
      append(div2, t3);
      append(div2, span0);
      ctx[9](span0);
      append(div2, t4);
      append(div2, span1);
      ctx[11](span1);
      current = true;
      if (!mounted) {
        dispose = [
          listen(
            span0,
            "click",
            /*click_handler*/
            ctx[10]
          ),
          listen(
            span1,
            "click",
            /*click_handler_1*/
            ctx[12]
          )
        ];
        mounted = true;
      }
    },
    p(ctx2, [dirty]) {
      if (!current || dirty & /*actionName*/
      1)
        set_data(
          t0,
          /*actionName*/
          ctx2[0]
        );
      if (dirty & /*_hotkeys, dispatcher*/
      48) {
        each_value = ensure_array_like(
          /*_hotkeys*/
          ctx2[4] ?? []
        );
        let i;
        for (i = 0; i < each_value.length; i += 1) {
          const child_ctx = get_each_context(ctx2, each_value, i);
          if (each_blocks[i]) {
            each_blocks[i].p(child_ctx, dirty);
            transition_in(each_blocks[i], 1);
          } else {
            each_blocks[i] = create_each_block(child_ctx);
            each_blocks[i].c();
            transition_in(each_blocks[i], 1);
            each_blocks[i].m(div1, t2);
          }
        }
        group_outros();
        for (i = each_value.length; i < each_blocks.length; i += 1) {
          out(i);
        }
        check_outros();
      }
      if (
        /*_listening*/
        ctx2[3]
      ) {
        if (if_block) {
        } else {
          if_block = create_if_block(ctx2);
          if_block.c();
          if_block.m(div1, null);
        }
      } else if (if_block) {
        if_block.d(1);
        if_block = null;
      }
    },
    i(local) {
      if (current)
        return;
      for (let i = 0; i < each_value.length; i += 1) {
        transition_in(each_blocks[i]);
      }
      current = true;
    },
    o(local) {
      each_blocks = each_blocks.filter(Boolean);
      for (let i = 0; i < each_blocks.length; i += 1) {
        transition_out(each_blocks[i]);
      }
      current = false;
    },
    d(detaching) {
      if (detaching) {
        detach(div3);
      }
      destroy_each(each_blocks, detaching);
      if (if_block)
        if_block.d();
      ctx[9](null);
      ctx[11](null);
      mounted = false;
      run_all(dispose);
    }
  };
}
var ICON_SIZE = 22;
function instance2($$self, $$props, $$invalidate) {
  let _hotkeys;
  let _listening;
  let { actionName } = $$props;
  let { hotkeys } = $$props;
  const listening = false;
  let restoreButtonEl;
  let addHotkeyButtonEl;
  const dispatcher = createEventDispatcher();
  onMount(() => {
    if (restoreButtonEl) {
      const component = new import_obsidian4.ExtraButtonComponent(restoreButtonEl).setTooltip("Restore default");
      (0, import_obsidian4.setIcon)(component.extraSettingsEl, "reset", ICON_SIZE);
    }
    if (addHotkeyButtonEl) {
      const component = new import_obsidian4.ExtraButtonComponent(addHotkeyButtonEl).setTooltip("Customize this action");
      (0, import_obsidian4.setIcon)(component.extraSettingsEl, "any-key", ICON_SIZE);
    }
  });
  const removed_handler = (hotkey) => {
    dispatcher("removed", { removed: hotkey });
  };
  function span0_binding($$value) {
    binding_callbacks[$$value ? "unshift" : "push"](() => {
      restoreButtonEl = $$value;
      $$invalidate(1, restoreButtonEl);
    });
  }
  const click_handler = () => {
    dispatcher("restored");
  };
  function span1_binding($$value) {
    binding_callbacks[$$value ? "unshift" : "push"](() => {
      addHotkeyButtonEl = $$value;
      $$invalidate(2, addHotkeyButtonEl);
    });
  }
  const click_handler_1 = () => {
    dispatcher("start-listening-keys");
  };
  $$self.$$set = ($$props2) => {
    if ("actionName" in $$props2)
      $$invalidate(0, actionName = $$props2.actionName);
    if ("hotkeys" in $$props2)
      $$invalidate(6, hotkeys = $$props2.hotkeys);
  };
  $$self.$$.update = () => {
    if ($$self.$$.dirty & /*hotkeys*/
    64) {
      $:
        $$invalidate(4, _hotkeys = [...hotkeys ?? []]);
    }
  };
  $:
    $$invalidate(3, _listening = listening);
  return [
    actionName,
    restoreButtonEl,
    addHotkeyButtonEl,
    _listening,
    _hotkeys,
    dispatcher,
    hotkeys,
    listening,
    removed_handler,
    span0_binding,
    click_handler,
    span1_binding,
    click_handler_1
  ];
}
var HotKeyEntry = class extends SvelteComponent {
  constructor(options) {
    super();
    init(this, options, instance2, create_fragment2, safe_not_equal, { actionName: 0, hotkeys: 6, listening: 7 }, add_css2);
  }
  get listening() {
    return this.$$.ctx[7];
  }
};
var HotKeyEntry_default = HotKeyEntry;

// src/ui/HotkeySetter.ts
var HotkeySetter = class {
  constructor(app2, containerEl, text2, currentHotkeys, defaultHotkeys) {
    this.shouldReflect = (_) => true;
    this.onRestored = () => {
      const { component } = this;
      if (!component)
        return;
      const renewed = [...this.defaultHotkeys];
      if (this.shouldReflect(renewed)) {
        this.currentHotkeys = renewed;
        component.$set({
          hotkeys: renewed
        });
      }
    };
    this.onRemoved = (evt) => {
      const { component } = this;
      if (!component)
        return;
      if (!(evt instanceof CustomEvent))
        return;
      const removed = evt.detail.removed;
      const renewed = [...this.currentHotkeys];
      renewed.remove(removed);
      if (this.shouldReflect(renewed)) {
        this.currentHotkeys = renewed;
        component.$set({
          hotkeys: renewed
        });
      }
    };
    this.onStartListening = () => {
      const { component } = this;
      if (!component)
        return;
      component.$set({
        listening: true
      });
      this.scope = new import_obsidian5.Scope();
      this.app.keymap.pushScope(this.scope);
      this.scope.register(null, null, (evt) => {
        evt.preventDefault();
        if (evt.key === "Escape") {
          component.$set({
            listening: false
          });
          if (this.scope)
            this.app.keymap.popScope(this.scope);
          return;
        }
        const hotkey = getHotkey(evt);
        const collision = contain(this.currentHotkeys, hotkey);
        if (collision)
          return;
        const renewed = [...this.currentHotkeys];
        renewed.push(hotkey);
        if (!this.shouldReflect(renewed, hotkey))
          return;
        this.currentHotkeys = renewed;
        component.$set({
          hotkeys: renewed
        });
        component.$set({
          listening: false
        });
        if (this.scope)
          this.app.keymap.popScope(this.scope);
      });
    };
    this.app = app2;
    this.containerEl = containerEl;
    this.text = text2;
    this.currentHotkeys = [...currentHotkeys];
    this.defaultHotkeys = [...defaultHotkeys];
    this.component = this.attachComponent();
  }
  unload() {
    this.onunload();
  }
  /**
   * @param cb : should return true if you want to adopt the current change
   */
  onChanged(cb) {
    this.shouldReflect = cb;
    return this;
  }
  attachComponent() {
    const component = new HotKeyEntry_default({
      target: this.containerEl,
      props: {
        actionName: this.text,
        hotkeys: this.currentHotkeys
      }
    });
    component.$on("removed", this.onRemoved);
    component.$on("restored", this.onRestored);
    component.$on("start-listening-keys", this.onStartListening);
    return component;
  }
  onunload() {
    this.component?.$destroy();
    if (this.scope) {
      this.app.keymap.popScope(this.scope);
    }
  }
};

// src/Setting.ts
var AVAILABLE_OUTLINE_WIDTHS = [0, 3, 5, 7, 10];
var AUTO_PREVIEW_MODE_IDS = ["none", "singleView", "cardView"];
var autoPreviewModeInfos = {
  none: "none",
  singleView: "single view",
  cardView: "card view"
};
var AVAILABLE_CARD_LAYOUT = ["2x2", "2x3", "3x2", "3x3"];
var DEFAULT_SETTINGS = {
  keepSelectedItemsCentered: false,
  outlineWidth: 5,
  autoPreviewMode: "cardView",
  cardViewLayout: "2x3",
  splitDirection: "horizontal",
  autoToggleSidebar: false,
  renderCardsManually: false,
  // hideIframe: false,
  searchModeHotkeys: {
    selectNext: [
      { modifiers: ["Ctrl"], key: "n" },
      { modifiers: [], key: "ArrowDown" }
    ],
    selectPrevious: [
      { modifiers: ["Ctrl"], key: "p" },
      { modifiers: [], key: "ArrowUp" }
    ],
    previewModal: [{ modifiers: ["Ctrl"], key: " " }],
    open: [{ modifiers: ["Ctrl"], key: "Enter" }],
    openInNewPane: [{ modifiers: ["Ctrl", "Shift"], key: "Enter" }],
    showOptions: [{ modifiers: ["Shift"], key: " " }],
    nextPage: [{ modifiers: ["Ctrl"], key: "]" }],
    previousPage: [{ modifiers: ["Ctrl"], key: "[" }],
    copyLink: [{ modifiers: ["Ctrl"], key: "i" }]
  },
  previewModalHotkeys: {
    scrollDown: [
      { modifiers: ["Ctrl"], key: "n" },
      { modifiers: [], key: "ArrowDown" }
    ],
    scrollUp: [
      { modifiers: ["Ctrl"], key: "p" },
      { modifiers: [], key: "ArrowUp" }
    ],
    bigScrollDown: [{ modifiers: [], key: " " }],
    bigScrollUp: [{ modifiers: ["Shift"], key: " " }],
    open: [{ modifiers: ["Ctrl"], key: "Enter" }],
    openInNewPage: [{ modifiers: ["Ctrl", "Shift"], key: "Enter" }],
    closeModal: [{ modifiers: ["Ctrl"], key: " " }],
    focusNext: [{ modifiers: [], key: "Tab" }],
    focusPrevious: [{ modifiers: ["Shift"], key: "Tab" }],
    togglePreviewMode: [{ modifiers: ["Ctrl"], key: "e" }],
    copyLink: [{ modifiers: ["Ctrl"], key: "i" }]
  }
};
var CoreSearchAssistantSettingTab = class extends import_obsidian6.PluginSettingTab {
  constructor(app2, plugin2) {
    super(app2, plugin2);
    this.plugin = plugin2;
    this.hotkeySetters = [];
  }
  display() {
    this.hide();
    const { containerEl } = this;
    containerEl.empty();
    new import_obsidian6.Setting(containerEl).setName("Keep selected item centered").addToggle((component) => {
      component.setValue(
        this.plugin.settings?.keepSelectedItemsCentered ?? DEFAULT_SETTINGS.keepSelectedItemsCentered
      ).onChange((value) => {
        if (!this.plugin.settings) {
          return;
        }
        this.plugin.settings.keepSelectedItemsCentered = value;
        this.plugin.saveSettings();
      });
    });
    new import_obsidian6.Setting(containerEl).setName("Outline width (px)").setDesc("An outline appears when you enter search mode.").addDropdown((component) => {
      AVAILABLE_OUTLINE_WIDTHS.forEach((width) => {
        const text2 = width.toString();
        component.addOption(text2, text2);
      });
      component.setValue(
        validOutlineWidth(this.plugin.settings?.outlineWidth).toString()
      ).onChange((value) => {
        const width = Number.parseInt(value);
        if (!this.plugin.settings) {
          return;
        }
        if (!AVAILABLE_OUTLINE_WIDTHS.includes(width)) {
          return;
        }
        this.plugin.settings.outlineWidth = width;
        this.plugin.saveSettings();
      });
    });
    new import_obsidian6.Setting(containerEl).setName("Auto preview mode").addDropdown((component) => {
      component.addOptions(autoPreviewModeInfos).setValue(this.plugin.settings?.autoPreviewMode ?? "cardView").onChange((id) => {
        if (!this.plugin.settings) {
          return;
        }
        if (!AUTO_PREVIEW_MODE_IDS.includes(id)) {
          return;
        }
        this.plugin.settings.autoPreviewMode = id;
        this.plugin.saveSettings();
      });
    });
    new import_obsidian6.Setting(containerEl).setName("Default layout of card view").addDropdown((component) => {
      AVAILABLE_CARD_LAYOUT.forEach((layout) => {
        component.addOption(layout, layout);
      });
      component.setValue(
        this.plugin.settings?.cardViewLayout ?? DEFAULT_SETTINGS.cardViewLayout
      ).onChange((value) => {
        if (!this.plugin.settings) {
          return;
        }
        if (!AVAILABLE_CARD_LAYOUT.includes(value)) {
          return;
        }
        this.plugin.settings.cardViewLayout = value;
        this.plugin.saveSettings();
      });
    });
    new import_obsidian6.Setting(containerEl).setName("Default split direction").setDesc("This applies when you open a file in a new pane").addDropdown((component) => {
      if (!this.plugin.settings) {
        return;
      }
      component.addOptions({
        horizontal: "horizontal",
        vertical: "vertical"
      }).setValue(this.plugin.settings.splitDirection).onChange(async (direction) => {
        if (!this.plugin.settings) {
          return;
        }
        if (direction === "horizontal" || direction === "vertical") {
          this.plugin.settings.splitDirection = direction;
          await this.plugin.saveSettings();
        }
      });
    });
    new import_obsidian6.Setting(containerEl).setName("Toggle sidebars automatically").setDesc(
      "Automatically collapse the other sidebar when entering the search mode and the search panel when exiting the search mode"
    ).addToggle((component) => {
      if (!this.plugin.settings) {
        return;
      }
      component.setValue(this.plugin.settings.autoToggleSidebar).onChange((value) => {
        if (!this.plugin.settings) {
          return;
        }
        this.plugin.settings.autoToggleSidebar = value;
        this.plugin.saveSettings();
      });
    });
    new import_obsidian6.Setting(containerEl).setName("Render cards manually").setDesc("If enabled, you must hit the enter key to render cards.").addToggle((component) => {
      if (!this.plugin.settings)
        return;
      component.setValue(this.plugin.settings.renderCardsManually).onChange((value) => {
        if (!this.plugin.settings)
          return;
        this.plugin.settings.renderCardsManually = value;
        this.plugin.saveSettings();
      });
    });
    containerEl.createEl("h2", { text: "Hotkeys" });
    const { settings } = this.plugin;
    containerEl.createEl("h3", { text: "Search mode" });
    if (!settings)
      return;
    SEARCH_MODE_HOTKEY_ACTION_IDS.forEach((actionId) => {
      const hotkeys = settings.searchModeHotkeys[actionId];
      const defaultHotkeys = DEFAULT_SETTINGS.searchModeHotkeys[actionId];
      const description = SEARCH_MODE_HOTKEY_ACTION_INFO[actionId];
      const hotkeySetter = new HotkeySetter(
        this.app,
        containerEl,
        description,
        hotkeys,
        defaultHotkeys
      ).onChanged((renewed, added) => {
        if (added) {
          if (added.modifiers.length === 0)
            return false;
          const collision = SEARCH_MODE_HOTKEY_ACTION_IDS.some((actionId2) => {
            const hotkeys2 = settings.searchModeHotkeys[actionId2];
            return contain(hotkeys2, added);
          });
          if (collision) {
            new import_obsidian6.Notice("Hotkeys are conflicting!");
            return false;
          }
        }
        settings.searchModeHotkeys[actionId] = renewed;
        this.plugin.saveSettings();
        return true;
      });
      this.hotkeySetters.push(hotkeySetter);
    });
    containerEl.createEl("h3", { text: "Preview Modal" });
    PREVIEW_MODAL_HOTKEY_ACTION_IDS.forEach((actionId) => {
      const hotkeys = settings.previewModalHotkeys[actionId];
      const defaultHotkeys = DEFAULT_SETTINGS.previewModalHotkeys[actionId];
      const description = PREVIEW_MODAL_HOTKEY_ACTION_INFO[actionId];
      DEFAULT_SETTINGS.previewModalHotkeys[actionId];
      const hotkeySetter = new HotkeySetter(
        this.app,
        containerEl,
        description,
        hotkeys,
        defaultHotkeys
      ).onChanged((renewed, added) => {
        if (added) {
          const collision = PREVIEW_MODAL_HOTKEY_ACTION_IDS.some((actionId2) => {
            const hotkeys2 = settings.previewModalHotkeys[actionId2];
            return contain(hotkeys2, added);
          });
          if (collision) {
            new import_obsidian6.Notice("Hotkeys are conflicting!");
            return false;
          }
        }
        settings.previewModalHotkeys[actionId] = renewed;
        this.plugin.saveSettings();
        return true;
      });
      this.hotkeySetters.push(hotkeySetter);
    });
  }
  hide() {
    super.hide();
    this.hotkeySetters.forEach((s) => s.unload());
    this.hotkeySetters = [];
  }
};
function validOutlineWidth(width) {
  if (typeof width !== "number") {
    return DEFAULT_SETTINGS.outlineWidth;
  }
  if (!Number.isInteger(width)) {
    return DEFAULT_SETTINGS.outlineWidth;
  }
  if (!AVAILABLE_OUTLINE_WIDTHS.includes(width)) {
    return DEFAULT_SETTINGS.outlineWidth;
  }
  return width;
}
function parseCardLayout(layout) {
  const [row, column] = layout.split("x");
  return [Number.parseInt(row ?? "0"), Number.parseInt(column ?? "0")];
}
var SEARCH_MODE_HOTKEY_ACTION_IDS = [
  "selectNext",
  "selectPrevious",
  "previewModal",
  "open",
  "openInNewPane",
  "showOptions",
  "nextPage",
  "previousPage",
  "copyLink"
];
var SEARCH_MODE_HOTKEY_ACTION_INFO = {
  selectNext: "Select the next item",
  selectPrevious: "Select the previous item",
  previewModal: "Preview the selected item",
  open: "Open the selected item",
  openInNewPane: "Open the selected item in a new pane",
  showOptions: "Set search options",
  nextPage: "Move to the next set of cards",
  previousPage: "Move to the previous set of cards",
  copyLink: "Copy wiki link of the selected item"
};
var PREVIEW_MODAL_HOTKEY_ACTION_IDS = [
  "scrollDown",
  "scrollUp",
  "bigScrollDown",
  "bigScrollUp",
  "open",
  "openInNewPage",
  "closeModal",
  "focusNext",
  "focusPrevious",
  "togglePreviewMode",
  "copyLink"
];
var PREVIEW_MODAL_HOTKEY_ACTION_INFO = {
  scrollDown: "Scroll down a bit",
  scrollUp: "Scroll up a bit",
  bigScrollDown: "Scroll down a lot",
  bigScrollUp: "Scroll up a lot",
  open: "Open the selected item",
  openInNewPage: "Open the selected item in a new pane",
  closeModal: "Close the modal",
  focusNext: "Focus on the next match",
  focusPrevious: "Focus on the previous match",
  togglePreviewMode: "Toggle preview mode",
  copyLink: "Copy wiki link of the selected item"
};

// src/components/OptionModal.ts
var import_obsidian7 = require("obsidian");

// src/types/Option.ts
var searchOptions = {
  matchingCase: {
    iconId: "uppercase-lowercase-a",
    description: "Toggle matching case"
  },
  explainSearch: {
    iconId: "info",
    description: "Toggle explanation of search term"
  },
  collapseAll: {
    iconId: "bullet-list",
    description: "Toggle collapsing results"
  },
  extraContext: {
    iconId: "expand-vertically",
    description: "Toggle showing more context"
  },
  alphabetical: {
    iconId: "down-arrow-with-tail",
    description: "Sort by file name (A \u2192 Z)"
  },
  alphabeticalReverse: {
    iconId: "up-arrow-with-tail",
    description: "Sort by file name (Z \u2192 A)"
  },
  byModifiedTime: {
    iconId: "down-arrow-with-tail",
    description: "Sort by modified time (new \u2192 old)"
  },
  byModifiedTimeReverse: {
    iconId: "up-arrow-with-tail",
    description: "Sort by modified time (old \u2192 new)"
  },
  byCreatedTime: {
    iconId: "down-arrow-with-tail",
    description: "Sort by created time (new \u2192 old)"
  },
  byCreatedTimeReverse: {
    iconId: "up-arrow-with-tail",
    description: "Sort by created time (old \u2192 new)"
  }
};

// src/components/OptionModal.ts
var OptionModal = class extends import_obsidian7.Modal {
  constructor(app2, plugin2, modeScope) {
    super(app2);
    this.plugin = plugin2;
    this.modeScope = modeScope;
    this.items = [
      {
        id: "matchingCase",
        key: "a",
        onChoose: () => {
          this.plugin.searchInterface?.toggleMatchingCase();
          this.plugin.searchInterface?.renewSortOrderInfo();
          this.plugin.controller?.reset();
        }
      },
      {
        id: "explainSearch",
        key: "s",
        onChoose: () => {
          this.plugin.searchInterface?.toggleExplainSearch();
        }
      },
      {
        id: "collapseAll",
        key: "d",
        onChoose: () => {
          this.plugin.searchInterface?.toggleCollapseAll();
        }
      },
      {
        id: "extraContext",
        key: "f",
        onChoose: () => {
          this.plugin.searchInterface?.toggleExtraContext();
        }
      },
      {
        id: "alphabetical",
        key: "g",
        onChoose: () => {
          const changed = this.plugin.searchInterface?.setSortOrder("alphabetical");
          if (changed) {
            this.plugin.searchInterface?.renewSortOrderInfo();
            this.plugin.controller?.reset();
          }
        }
      },
      {
        id: "alphabeticalReverse",
        key: "h",
        onChoose: () => {
          const changed = this.plugin.searchInterface?.setSortOrder(
            "alphabeticalReverse"
          );
          if (changed) {
            this.plugin.searchInterface?.renewSortOrderInfo();
            this.plugin.controller?.reset();
          }
        }
      },
      {
        id: "byModifiedTime",
        key: "j",
        onChoose: () => {
          const changed = this.plugin.searchInterface?.setSortOrder("byModifiedTime");
          if (changed) {
            this.plugin.searchInterface?.renewSortOrderInfo();
            this.plugin.controller?.reset();
          }
        }
      },
      {
        id: "byModifiedTimeReverse",
        key: "k",
        onChoose: () => {
          const changed = this.plugin.searchInterface?.setSortOrder(
            "byModifiedTimeReverse"
          );
          if (changed) {
            this.plugin.searchInterface?.renewSortOrderInfo();
            this.plugin.controller?.reset();
          }
        }
      },
      {
        id: "byCreatedTime",
        key: "l",
        onChoose: () => {
          const changed = this.plugin.searchInterface?.setSortOrder("byCreatedTime");
          if (changed) {
            this.plugin.searchInterface?.renewSortOrderInfo();
            this.plugin.controller?.reset();
          }
        }
      },
      {
        id: "byCreatedTimeReverse",
        key: ";",
        onChoose: () => {
          const changed = this.plugin.searchInterface?.setSortOrder(
            "byCreatedTimeReverse"
          );
          if (changed) {
            this.plugin.searchInterface?.renewSortOrderInfo();
            this.plugin.controller?.reset();
          }
        }
      }
    ];
  }
  onOpen() {
    this.modeScope.push();
    this.items.forEach((item) => {
      this.scope.register([], item.key, item.onChoose);
    });
    this.renderOptions();
  }
  onClose() {
    const { containerEl } = this;
    containerEl.empty();
    setTimeout(() => this.modeScope.pop(), 100);
  }
  renderOptions() {
    const { contentEl } = this;
    contentEl.empty();
    this.containerEl.addClass("core-search-assistant_option-modal");
    this.items.forEach((item) => {
      const entryEl = contentEl.createEl("div", {
        cls: "suggestion-item"
      });
      const iconEl = entryEl.createEl("span", {
        cls: "suggestion-icon"
      });
      (0, import_obsidian7.setIcon)(iconEl, searchOptions[item.id].iconId);
      entryEl.createEl("span", {
        text: searchOptions[item.id].description,
        cls: "suggestion-content"
      });
      entryEl.createEl("kbd", {
        text: item.key.toUpperCase(),
        cls: "suggestion-hotkey"
      });
    });
  }
};

// src/components/PreviewModal.ts
var import_obsidian13 = require("obsidian");

// src/interfaces/ViewGenerator.ts
var import_obsidian8 = require("obsidian");

// src/utils/Util.ts
async function delay(millisecond) {
  await new Promise((resolve) => setTimeout(resolve, millisecond));
}
function scrollIteration(editor) {
  const line = lineCount(editor);
  if (line === void 0) {
    return void 0;
  }
  return Math.max(Math.floor(line / 1e3), 1);
}
function lineCount(editor) {
  const line = editor?.cm?.state?.doc?.length;
  return typeof line === "number" ? line : void 0;
}
async function retry(cb, interval, trials, check = (got) => got !== void 0) {
  for (let i = 0; i < trials; i++) {
    const got = cb();
    if (check(got)) {
      return got;
    }
    await delay(interval);
  }
  return void 0;
}
function shallowClone(obj) {
  return Object.assign({}, obj);
}
function deepClone(obj) {
  if (obj === null)
    return obj;
  if (typeof obj !== "object")
    return obj;
  if (Array.isArray(obj)) {
    const clone2 = new Array(obj.length);
    obj.forEach((value, id) => {
      clone2[id] = deepClone(value);
    });
    return clone2;
  }
  const clone = shallowClone(obj);
  for (const key in clone) {
    const value = clone[key];
    clone[key] = deepClone(value);
  }
  return clone;
}
function deepMerge(a, b) {
  if (b === void 0) {
    return deepClone(a);
  }
  if (a === void 0) {
    return deepClone(b);
  }
  if (typeof a !== typeof b) {
    throw new Error(`failed to deepMerge ${a} and ${b}`);
  }
  if (typeof b !== "object")
    return deepClone(b);
  if (b === null) {
    return deepClone(a);
  }
  if (a === null) {
    return deepClone(b);
  }
  if (Array.isArray(b)) {
    if (Array.isArray(a)) {
      return deepClone(b);
    }
    throw new Error(`failed to deepMerge ${a} and ${b}`);
  }
  if (Array.isArray(a)) {
    throw new Error(`failed to deepMerge ${a} and ${b}`);
  }
  const clone = shallowClone(a);
  for (const key in a) {
    clone[key] = deepMerge(a[key], b[key]);
  }
  for (const key in b) {
    clone[key] = deepMerge(a[key], b[key]);
  }
  return clone;
}

// src/interfaces/ViewGenerator.ts
var ViewGenerator = class {
  constructor(app2, containerEl, file) {
    this.extensions = [];
    this.app = app2;
    this.containerEl = containerEl;
    this.leaf = new import_obsidian8.WorkspaceLeaf(this.app);
    this.file = file;
  }
  async load(mode) {
    await this.onload(mode);
    return this;
  }
  async unload() {
    this.onunload();
  }
  async toggleViewMode() {
    for (const ext of this.extensions) {
      if (!await ext.isMine(this.leaf))
        continue;
      await ext.toggleViewMode(this.leaf);
      return;
    }
  }
  async onload(mode) {
    const fileType = fileTypeMap[this.file.extension];
    if (!fileType)
      return;
    this.containerEl.appendChild(this.leaf.containerEl);
    await this.openFile();
    for (const ext of this.extensions) {
      if (!await ext.isMine(this.leaf))
        continue;
      await ext.setViewMode(this.leaf, mode ?? "preview");
      return;
    }
  }
  onunload() {
    this.leaf.detach();
  }
  async openFile() {
    const { leaf, file } = this;
    await leaf.openFile(file);
  }
  // it should be called once because is is not idempotent
  // it can be called even when view mode = 'preview'
  highlightMatches(matches, cls) {
    const view = this.leaf.view;
    if (!(view instanceof import_obsidian8.MarkdownView)) {
      return;
    }
    const editor = view.editor;
    const ranges = [];
    matches.forEach((match) => {
      const range = {
        from: editor.offsetToPos(match[0]),
        to: editor.offsetToPos(match[1])
      };
      ranges.push(range);
    });
    editor.addHighlights(ranges, cls);
  }
  async scrollIntoView(match, center) {
    const view = this.leaf.view;
    if (!(view instanceof import_obsidian8.MarkdownView)) {
      return;
    }
    if (view.getMode() !== "source") {
      return;
    }
    const editor = view.editor;
    const range = {
      from: editor.offsetToPos(match[0]),
      to: editor.offsetToPos(match[1])
    };
    const iter = scrollIteration(editor);
    if (iter === void 0) {
      return;
    }
    for (let i = 0; i < iter; i++) {
      editor.scrollIntoView(range, center);
      await delay(1);
    }
  }
  async focusOn(match, cls, center) {
    const view = this.leaf.view;
    if (!(view instanceof import_obsidian8.MarkdownView)) {
      return;
    }
    if (view.getMode() !== "source") {
      return;
    }
    await this.scrollIntoView(match, center);
    const { editor } = view;
    editor.removeHighlights(cls);
    const range = {
      from: editor.offsetToPos(match[0]),
      to: editor.offsetToPos(match[1])
    };
    editor.addHighlights([range], cls);
  }
  registerExtension(ext) {
    this.extensions.push(ext);
    return this;
  }
};
var fileTypeMap = {
  md: "md",
  png: "image",
  jpg: "image",
  jpeg: "image",
  gif: "image",
  bmp: "image",
  svg: "image",
  webp: "image",
  mp3: "audio",
  webm: "audio",
  wav: "audio",
  m4a: "audio",
  ogg: "audio",
  "3gp": "audio",
  flac: "audio",
  mp4: "movie",
  ogv: "movie",
  pdf: "pdf"
};

// src/interfaces/viewGeneratorExtensions/Excalidraw.ts
var import_obsidian9 = require("obsidian");
var excalidrawPluginId = "obsidian-excalidraw-plugin";
var excalidrawViewType = "excalidraw";
var ExcalidrawViewGeneratorExtension = class {
  constructor(app2) {
    this.app = app2;
    const excalidraw = this.app.plugins.plugins[excalidrawPluginId];
    if (!isExcalidrawPlugin(excalidraw)) {
      this.excalidraw = void 0;
    } else {
      this.excalidraw = excalidraw;
    }
  }
  isMine(leaf) {
    return leaf.view.getViewType() === excalidrawViewType;
  }
  // https://github.com/zsviczian/obsidian-excalidraw-plugin/blob/109fe05302bde0e8fe4e97c3bad6ca3f51f6b6b1/src/main.ts#L953-L986
  async setViewMode(leaf, mode) {
    const { excalidraw } = this;
    if (!excalidraw)
      return;
    excalidraw.excalidrawFileModes[leaf.id] = "markdown";
    await excalidraw.setMarkdownView(leaf);
    if (!(leaf.view instanceof import_obsidian9.MarkdownView))
      return;
    await leaf.view.setState(
      {
        ...leaf.view.getState(),
        mode
      },
      {}
    );
    leaf.view.editor.blur();
  }
  async toggleViewMode(leaf) {
    const { excalidraw } = this;
    if (!excalidraw)
      return;
    excalidraw.excalidrawFileModes[leaf.id] = "markdown";
    await excalidraw.setMarkdownView(leaf);
    if (!(leaf.view instanceof import_obsidian9.MarkdownView))
      return;
    const mode = leaf.view.getMode();
    await leaf.view.setState(
      {
        ...leaf.view.getState(),
        mode: mode === "preview" ? "source" : "preview"
      },
      {}
    );
    leaf.view.editor.blur();
  }
};
function isExcalidrawPlugin(plugin2) {
  if (!(plugin2 instanceof import_obsidian9.Plugin))
    return false;
  const { excalidrawFileModes, setMarkdownView } = plugin2;
  if (typeof excalidrawFileModes !== "object")
    return false;
  if (typeof setMarkdownView !== "function")
    return false;
  return true;
}

// src/interfaces/viewGeneratorExtensions/Kanban.ts
var import_obsidian10 = require("obsidian");
var kanbanPluginId = "obsidian-kanban";
var frontMatterKey = "kanban-plugin";
var kanbanViewType = "kanban";
var KanbanViewGeneratorExtension = class {
  constructor(app2) {
    this.app = app2;
    const kanban = this.app.plugins.plugins[kanbanPluginId];
    if (IsKanbanPlugin(kanban)) {
      this.kanban = kanban;
    }
    if (kanban === void 0) {
      this.kanban = void 0;
    }
  }
  isMine(leaf) {
    const { view } = leaf;
    if (view.getViewType() === kanbanViewType)
      return true;
    if (!(view instanceof import_obsidian10.TextFileView))
      return false;
    const fileCache = this.app.metadataCache.getFileCache(view.file);
    const fileIsKanban = !!fileCache?.frontmatter && !!fileCache.frontmatter[frontMatterKey];
    return fileIsKanban;
  }
  // https://github.com/mgmeyers/obsidian-kanban/blob/350fc891a8489f70551d288ae914534424c8c095/src/main.ts#L317-L345
  async setViewMode(leaf, mode) {
    const { kanban } = this;
    if (!kanban)
      return;
    if (mode === "source") {
      kanban.kanbanFileModes[leaf.id] = "markdown";
      await kanban.setMarkdownView(leaf);
      await leaf.view.setState(
        {
          ...leaf.view.getState(),
          mode: "source"
        },
        {}
      );
      if (leaf.view instanceof import_obsidian10.MarkdownView) {
        leaf.view.editor.blur();
      }
    } else {
      kanban.kanbanFileModes[leaf.id] = kanbanViewType;
      await kanban.setKanbanView(leaf);
    }
  }
  async toggleViewMode(leaf) {
    const { kanban } = this;
    if (!kanban)
      return;
    const mode = kanban.kanbanFileModes[leaf.id];
    await this.setViewMode(leaf, mode === "markdown" ? "preview" : "source");
  }
};
function IsKanbanPlugin(plugin2) {
  if (!(plugin2 instanceof import_obsidian10.Plugin))
    return false;
  const { kanbanFileModes, setKanbanView, setMarkdownView } = plugin2;
  if (typeof kanbanFileModes !== "object")
    return false;
  if (typeof setMarkdownView !== "function")
    return false;
  if (typeof setKanbanView !== "function")
    return false;
  return true;
}

// src/interfaces/viewGeneratorExtensions/Markdown.ts
var import_obsidian11 = require("obsidian");
var MarkdownViewGeneratorExtension = class {
  isMine(leaf) {
    return leaf.view instanceof import_obsidian11.MarkdownView;
  }
  async setViewMode(leaf, mode) {
    await leaf.view.setState(
      {
        ...leaf.view.getState(),
        mode
      },
      {}
    );
  }
  async toggleViewMode(leaf) {
    if (!(leaf.view instanceof import_obsidian11.MarkdownView))
      return;
    await this.setViewMode(
      leaf,
      leaf.view.getMode() === "preview" ? "source" : "preview"
    );
  }
};

// src/interfaces/viewGeneratorExtensions/NonMarkdown.ts
var import_obsidian12 = require("obsidian");
var NON_MARKDOWN_FILE_TYPES = ["image", "audio", "pdf", "video"];
var NonMarkdownViewGeneratorExtension = class {
  isMine(leaf) {
    if (!(leaf.view instanceof import_obsidian12.FileView))
      return false;
    return NON_MARKDOWN_FILE_TYPES.includes(
      leaf.view.getViewType()
    );
  }
  setViewMode(_leaf, _mode) {
    return;
  }
  toggleViewMode(_) {
    return;
  }
};

// node_modules/svelte/src/runtime/store/index.js
var subscriber_queue = [];
function writable(value, start = noop) {
  let stop;
  const subscribers = /* @__PURE__ */ new Set();
  function set(new_value) {
    if (safe_not_equal(value, new_value)) {
      value = new_value;
      if (stop) {
        const run_queue = !subscriber_queue.length;
        for (const subscriber of subscribers) {
          subscriber[1]();
          subscriber_queue.push(subscriber, value);
        }
        if (run_queue) {
          for (let i = 0; i < subscriber_queue.length; i += 2) {
            subscriber_queue[i][0](subscriber_queue[i + 1]);
          }
          subscriber_queue.length = 0;
        }
      }
    }
  }
  function update2(fn) {
    set(fn(value));
  }
  function subscribe2(run2, invalidate = noop) {
    const subscriber = [run2, invalidate];
    subscribers.add(subscriber);
    if (subscribers.size === 1) {
      stop = start(set, update2) || noop;
    }
    run2(value);
    return () => {
      subscribers.delete(subscriber);
      if (subscribers.size === 0 && stop) {
        stop();
        stop = null;
      }
    };
  }
  return { set, update: update2, subscribe: subscribe2 };
}

// src/ui/store.ts
var app = writable();
var plugin = writable();

// src/ui/PreviewModalContent.svelte
function add_css3(target) {
  append_styles(target, "svelte-6cqu2r", ".core-search-assistant_preview-modal_view-container.svelte-6cqu2r{min-width:700px}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .highlight-search-match{color:var(--highlight-search-match);background-color:var(--highlight-search-match-bg)}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .focus-search-match{background-color:var(--focus-search-match-bg)}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .workspace-leaf{contain:initial !important}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .view-content{overflow:unset}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .markdown-preview-view{overflow:unset}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .workspace-leaf-content{overflow:unset}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .workspace-leaf-resize-handle{display:none}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .view-header{display:none}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .markdown-preview-view{padding:0}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .markdown-source-view{pointer-events:none}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .workspace-leaf-content[data-type='pdf']{height:990px}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .markdown-source-view.mod-cm6 .cm-editor{flex:initial;display:initial}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .markdown-source-view.mod-cm6{display:initial}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .markdown-source-view.mod-cm6 .cm-scroller{padding:0}");
}
function create_fragment3(ctx) {
  let div;
  return {
    c() {
      div = element("div");
      attr(div, "class", "core-search-assistant_preview-modal_view-container svelte-6cqu2r");
    },
    m(target, anchor) {
      insert(target, div, anchor);
      ctx[5](div);
    },
    p: noop,
    i: noop,
    o: noop,
    d(detaching) {
      if (detaching) {
        detach(div);
      }
      ctx[5](null);
    }
  };
}
function instance3($$self, $$props, $$invalidate) {
  let $app;
  component_subscribe($$self, app, ($$value) => $$invalidate(7, $app = $$value));
  let { file } = $$props;
  let { matches } = $$props;
  let contentContainerEl;
  let renderer;
  onMount(async () => {
    if (!file) {
      return;
    }
    if (!contentContainerEl) {
      return;
    }
    const fileType = fileTypeMap[file.extension];
    if (fileType !== void 0) {
      contentContainerEl.empty();
      renderer = await new ViewGenerator($app, contentContainerEl, file).registerExtension(new ExcalidrawViewGeneratorExtension($app)).registerExtension(new KanbanViewGeneratorExtension($app)).registerExtension(new MarkdownViewGeneratorExtension()).registerExtension(new NonMarkdownViewGeneratorExtension()).load("source");
      highlightMatches();
    }
  });
  onDestroy(() => {
    setTimeout(() => renderer?.unload(), 1e3);
  });
  async function toggleViewMode() {
    await renderer?.toggleViewMode();
  }
  function focusOn(matchId, center) {
    if (!matches)
      return;
    const match = matches[matchId];
    if (match === void 0) {
      return;
    }
    renderer?.focusOn(match, "focus-search-match", center);
  }
  function highlightMatches() {
    renderer?.highlightMatches(matches ?? [], "highlight-search-match");
  }
  function div_binding($$value) {
    binding_callbacks[$$value ? "unshift" : "push"](() => {
      contentContainerEl = $$value;
      $$invalidate(0, contentContainerEl);
    });
  }
  $$self.$$set = ($$props2) => {
    if ("file" in $$props2)
      $$invalidate(1, file = $$props2.file);
    if ("matches" in $$props2)
      $$invalidate(2, matches = $$props2.matches);
  };
  return [contentContainerEl, file, matches, toggleViewMode, focusOn, div_binding];
}
var PreviewModalContent = class extends SvelteComponent {
  constructor(options) {
    super();
    init(
      this,
      options,
      instance3,
      create_fragment3,
      safe_not_equal,
      {
        file: 1,
        matches: 2,
        toggleViewMode: 3,
        focusOn: 4
      },
      add_css3
    );
  }
  get toggleViewMode() {
    return this.$$.ctx[3];
  }
  get focusOn() {
    return this.$$.ctx[4];
  }
};
var PreviewModalContent_default = PreviewModalContent;

// src/utils/Link.ts
function generateInternalLinkFrom(app2, file) {
  const text2 = getDisplayText(app2.metadataCache, file);
  return app2.fileManager.generateMarkdownLink(file, "", void 0, text2);
}
function getDisplayText(metadataCache, file) {
  const cache = metadataCache.getFileCache(file);
  if (!cache)
    return void 0;
  const title = getTitle(cache.frontmatter);
  if (title !== void 0) {
    return title;
  }
  const h1 = getFirstH1(cache.headings);
  if (h1 !== void 0) {
    return h1;
  }
  return void 0;
}
function getTitle(frontmatter) {
  return frontmatter?.title;
}
function getFirstH1(headings) {
  if (!headings)
    return void 0;
  for (const heading of headings) {
    if (heading.level !== 1)
      continue;
    return heading.heading;
  }
  return void 0;
}

// src/components/PreviewModal.ts
var SCROLL_AMOUNT = 70;
var PreviewModal = class extends import_obsidian13.Modal {
  constructor(app2, plugin2, modeScope, item) {
    super(app2);
    this.plugin = plugin2;
    this.modeScope = modeScope;
    this.item = item;
    this.currentFocus = -1;
  }
  async onOpen() {
    await this.renderView();
    this.modeScope.push();
    const hotkeyMap = this.plugin.settings?.previewModalHotkeys;
    if (!hotkeyMap)
      return;
    hotkeyMap.closeModal.forEach((hotkey) => {
      this.scope.register(hotkey.modifiers, hotkey.key, () => {
        this.shouldRestoreSelection = true;
        this.close();
      });
    });
    hotkeyMap.open.forEach((hotkey) => {
      this.scope.register(hotkey.modifiers, hotkey.key, () => {
        this.openAndFocus(this.currentFocus);
        this.plugin.controller?.exit();
        this.shouldRestoreSelection = false;
        this.close();
      });
    });
    hotkeyMap.openInNewPage.forEach((hotkey) => {
      this.scope.register(hotkey.modifiers, hotkey.key, () => {
        this.openAndFocus(
          this.currentFocus,
          this.plugin.settings?.splitDirection
        );
        this.plugin.controller?.exit();
        this.shouldRestoreSelection = false;
        this.close();
      });
    });
    hotkeyMap.bigScrollDown.forEach((hotkey) => {
      this.scope.register(hotkey.modifiers, hotkey.key, () => {
        this.scroll("down");
      });
    });
    hotkeyMap.bigScrollUp.forEach((hotkey) => {
      this.scope.register(hotkey.modifiers, hotkey.key, () => {
        this.scroll("up");
      });
    });
    hotkeyMap.scrollDown.forEach((hotkey) => {
      this.scope.register(hotkey.modifiers, hotkey.key, () => {
        this.scroll("down", SCROLL_AMOUNT);
      });
    });
    hotkeyMap.scrollUp.forEach((hotkey) => {
      this.scope.register(hotkey.modifiers, hotkey.key, () => {
        this.scroll("up", SCROLL_AMOUNT);
      });
    });
    hotkeyMap.focusNext.forEach((hotkey) => {
      this.scope.register(hotkey.modifiers, hotkey.key, (evt) => {
        evt.preventDefault();
        const numMatches = this.countMatches();
        if (numMatches === void 0 || numMatches === 0) {
          return;
        }
        this.currentFocus = cyclicId(++this.currentFocus, numMatches);
        this.previewContent?.focusOn(this.currentFocus, true);
      });
    });
    hotkeyMap.focusPrevious.forEach((hotkey) => {
      this.scope.register(hotkey.modifiers, hotkey.key, (evt) => {
        evt.preventDefault();
        const numMatches = this.countMatches();
        if (numMatches === void 0 || numMatches === 0) {
          return;
        }
        this.currentFocus = cyclicId(--this.currentFocus, numMatches);
        this.previewContent?.focusOn(this.currentFocus, true);
      });
    });
    hotkeyMap.togglePreviewMode.forEach((hotkey) => {
      this.scope.register(hotkey.modifiers, hotkey.key, (evt) => {
        (async () => {
          evt.preventDefault();
          await this.previewContent?.toggleViewMode();
        })();
      });
    });
    hotkeyMap.copyLink.forEach((hotkey) => {
      this.scope.register(hotkey.modifiers, hotkey.key, () => {
        const { file } = this.item;
        const internalLink = generateInternalLinkFrom(this.app, file);
        navigator.clipboard.writeText(internalLink);
        new import_obsidian13.Notice("Copy wiki link!");
      });
    });
  }
  onClose() {
    this.previewContent?.$destroy();
    setTimeout(() => {
      if (this.modeScope.depth > 1) {
        this.modeScope.pop();
      }
    }, 100);
  }
  async renderView() {
    const { contentEl } = this;
    contentEl.empty();
    contentEl.hide();
    this.previewContent = new PreviewModalContent_default({
      target: contentEl,
      props: {
        file: this.item.file,
        matches: this.item.result.content
      }
    });
    contentEl.show();
  }
  countMatches() {
    return this.item.result.content?.length;
  }
  scroll(direction, px) {
    const { containerEl, contentEl } = this;
    const move = (px ?? containerEl.clientHeight / 2) * (direction === "up" ? -1 : 1);
    contentEl.scrollBy({
      top: move,
      behavior: "smooth"
    });
  }
  async openAndFocus(matchId, direction) {
    const { item } = this;
    const leaf = direction === void 0 ? this.app.workspace.getMostRecentLeaf() : this.app.workspace.splitActiveLeaf(direction);
    await leaf.openFile(item.file);
    this.app.workspace.setActiveLeaf(leaf, true, true);
    const match = item?.result?.content?.[matchId];
    if (!match) {
      return;
    }
    const { view } = leaf;
    if (!(view instanceof import_obsidian13.MarkdownView)) {
      return;
    }
    const editor = view.editor;
    const range = {
      from: editor.offsetToPos(match[0]),
      to: editor.offsetToPos(match[1])
    };
    editor.addHighlights([range], "obsidian-search-match-highlight");
    const iter = scrollIteration(editor);
    if (iter === void 0) {
      return;
    }
    for (let i = 0; i < iter; i++) {
      editor.scrollIntoView(range, true);
    }
    editor.setCursor(range.from);
  }
};
function cyclicId(id, total) {
  return (id % total + total) % total;
}

// src/Controller.ts
var obsidian = __toESM(require("obsidian"), 1);
var import_obsidian14 = require("obsidian");

// src/ui/CardContainer.svelte
function add_css4(target) {
  append_styles(target, "svelte-1g7kfgn", ".core-search-assistant_card-container.svelte-1g7kfgn.svelte-1g7kfgn{overflow:hidden;display:flex;flex-direction:column;height:100%;position:relative;box-shadow:0 2px 5px rgba(0, 0, 0, 0.2);border-radius:10px;cursor:pointer;background-color:var(--background-primary);box-sizing:content-box}.core-search-assistant_card-container.svelte-1g7kfgn.svelte-1g7kfgn:hover{border:5px solid var(--interactive-accent);margin:-5px}.core-search-assistant_card-container.is-selected.svelte-1g7kfgn.svelte-1g7kfgn{border:5px solid var(--interactive-accent);margin:-5px}.card-container-header.svelte-1g7kfgn.svelte-1g7kfgn{padding:5px 10px;background-color:var(--background-secondary);display:flex;color:var(--text-muted)}.file-name-container.svelte-1g7kfgn.svelte-1g7kfgn{font-size:1rem;line-height:1.2rem;overflow-wrap:break-word;min-width:0;flex:1}.file-name-container.svelte-1g7kfgn span.matched-in-path{color:var(--text-normal);font-weight:bold}.content-container-wrapper.svelte-1g7kfgn.svelte-1g7kfgn{padding:5px;flex:1;height:100%;min-height:0}.content-container.svelte-1g7kfgn.svelte-1g7kfgn{overflow:hidden;height:100%;font-size:0.8rem;line-height:1.2}.content-container.svelte-1g7kfgn div.content-not-supported-file-format.svelte-1g7kfgn{font-size:1rem;color:var(--text-muted)}.content-container.svelte-1g7kfgn p{font-size:0.8rem;line-height:1.2}.content-container.svelte-1g7kfgn code{font-size:0.8rem;line-height:1.2}.content-container.svelte-1g7kfgn div{font-size:0.8rem}.content-container.svelte-1g7kfgn li{font-size:0.8rem;line-height:1.2}.content-container.svelte-1g7kfgn h1{font-size:1rem;line-height:1.2;margin:5px}.content-container.svelte-1g7kfgn h2{font-size:1rem;line-height:1.2;margin:5px}.content-container.svelte-1g7kfgn h3{font-size:1rem;line-height:1.2;margin:5px}.content-container.svelte-1g7kfgn h4{font-size:1rem;line-height:1.2;margin:5px}.content-container.svelte-1g7kfgn h5{font-size:1rem;line-height:1.2;margin:5px}.content-container.svelte-1g7kfgn h6{font-size:1rem;line-height:1.2;margin:5px}.content-container.svelte-1g7kfgn a{pointer-events:none}.content-container.svelte-1g7kfgn .workspace-leaf{contain:initial !important;height:100%}.content-container.svelte-1g7kfgn .workspace-leaf-resize-handle{display:none}.content-container.svelte-1g7kfgn .view-header{display:none}.content-container.svelte-1g7kfgn .view-content{flex:1;overflow:hidden}.content-container.svelte-1g7kfgn .markdown-preview-view{padding:0;overflow:hidden}.content-container.svelte-1g7kfgn .modal-content{margin:0}");
}
function create_fragment4(ctx) {
  let div5;
  let div1;
  let div0;
  let t0;
  let div4;
  let div3;
  let div2;
  let t1_value = `${/*file*/
  ctx[1].extension.toUpperCase()} file`;
  let t1;
  let div5_data_path_value;
  let mounted;
  let dispose;
  return {
    c() {
      div5 = element("div");
      div1 = element("div");
      div0 = element("div");
      t0 = space();
      div4 = element("div");
      div3 = element("div");
      div2 = element("div");
      t1 = text(t1_value);
      attr(div0, "class", "file-name-container svelte-1g7kfgn");
      attr(div1, "class", "card-container-header svelte-1g7kfgn");
      attr(div2, "class", "content-not-supported-file-format svelte-1g7kfgn");
      attr(div3, "class", "content-container svelte-1g7kfgn");
      attr(div4, "class", "content-container-wrapper svelte-1g7kfgn");
      attr(div5, "class", "core-search-assistant_card-container svelte-1g7kfgn");
      attr(
        div5,
        "data-id",
        /*id*/
        ctx[0]
      );
      attr(div5, "data-path", div5_data_path_value = /*file*/
      ctx[1].path);
      attr(div5, "role", "button");
      toggle_class(
        div5,
        "is-selected",
        /*selected*/
        ctx[2]
      );
    },
    m(target, anchor) {
      insert(target, div5, anchor);
      append(div5, div1);
      append(div1, div0);
      ctx[8](div0);
      append(div5, t0);
      append(div5, div4);
      append(div4, div3);
      append(div3, div2);
      append(div2, t1);
      ctx[9](div3);
      if (!mounted) {
        dispose = listen(
          div5,
          "click",
          /*onClicked*/
          ctx[5]
        );
        mounted = true;
      }
    },
    p(ctx2, [dirty]) {
      if (dirty & /*file*/
      2 && t1_value !== (t1_value = `${/*file*/
      ctx2[1].extension.toUpperCase()} file`))
        set_data(t1, t1_value);
      if (dirty & /*id*/
      1) {
        attr(
          div5,
          "data-id",
          /*id*/
          ctx2[0]
        );
      }
      if (dirty & /*file*/
      2 && div5_data_path_value !== (div5_data_path_value = /*file*/
      ctx2[1].path)) {
        attr(div5, "data-path", div5_data_path_value);
      }
      if (dirty & /*selected*/
      4) {
        toggle_class(
          div5,
          "is-selected",
          /*selected*/
          ctx2[2]
        );
      }
    },
    i: noop,
    o: noop,
    d(detaching) {
      if (detaching) {
        detach(div5);
      }
      ctx[8](null);
      ctx[9](null);
      mounted = false;
      dispose();
    }
  };
}
function renderFileName(fileName, containerEl) {
  containerEl.appendText(fileName);
}
function instance4($$self, $$props, $$invalidate) {
  let $app;
  component_subscribe($$self, app, ($$value) => $$invalidate(11, $app = $$value));
  let { id } = $$props;
  let { file } = $$props;
  let { selected } = $$props;
  let { focusEl } = $$props;
  let contentContainerEl;
  let fileNameContainerEl;
  let renderer;
  const dispatch = createEventDispatcher();
  function path() {
    return file.path;
  }
  onMount(async () => {
    if (!fileNameContainerEl) {
      return;
    }
    renderFileName(file.name, fileNameContainerEl);
    if (!contentContainerEl) {
      return;
    }
    const fileType = fileTypeMap[file.extension];
    if (fileType !== void 0) {
      contentContainerEl.empty();
      renderer = await new ViewGenerator($app, contentContainerEl, file).registerExtension(new ExcalidrawViewGeneratorExtension($app)).registerExtension(new KanbanViewGeneratorExtension($app)).registerExtension(new MarkdownViewGeneratorExtension()).registerExtension(new NonMarkdownViewGeneratorExtension()).load("preview");
    }
    focusEl?.focus();
  });
  onDestroy(() => {
    setTimeout(() => renderer?.unload(), 1e3);
  });
  async function onClicked() {
    await openFile();
    dispatch("click");
  }
  async function openFile() {
    const leaf = $app.workspace.getMostRecentLeaf();
    await leaf.openFile(file);
    $app.workspace.setActiveLeaf(leaf, true, true);
  }
  function div0_binding($$value) {
    binding_callbacks[$$value ? "unshift" : "push"](() => {
      fileNameContainerEl = $$value;
      $$invalidate(4, fileNameContainerEl);
    });
  }
  function div3_binding($$value) {
    binding_callbacks[$$value ? "unshift" : "push"](() => {
      contentContainerEl = $$value;
      $$invalidate(3, contentContainerEl);
    });
  }
  $$self.$$set = ($$props2) => {
    if ("id" in $$props2)
      $$invalidate(0, id = $$props2.id);
    if ("file" in $$props2)
      $$invalidate(1, file = $$props2.file);
    if ("selected" in $$props2)
      $$invalidate(2, selected = $$props2.selected);
    if ("focusEl" in $$props2)
      $$invalidate(6, focusEl = $$props2.focusEl);
  };
  return [
    id,
    file,
    selected,
    contentContainerEl,
    fileNameContainerEl,
    onClicked,
    focusEl,
    path,
    div0_binding,
    div3_binding
  ];
}
var CardContainer = class extends SvelteComponent {
  constructor(options) {
    super();
    init(
      this,
      options,
      instance4,
      create_fragment4,
      safe_not_equal,
      {
        id: 0,
        file: 1,
        selected: 2,
        focusEl: 6,
        path: 7
      },
      add_css4
    );
  }
  get path() {
    return this.$$.ctx[7];
  }
};
var CardContainer_default = CardContainer;

// src/ui/CardViewComponent.svelte
function add_css5(target) {
  append_styles(target, "svelte-pwex1j", ".card-view-container.svelte-pwex1j{position:absolute;top:0;left:0;width:100%;height:100%;z-index:var(--layer-modal);padding:20px 30px;display:flex;justify-content:center}.card-view-background.svelte-pwex1j{position:absolute;top:0;left:0;width:100%;height:100%;background-color:var(--background-modifier-cover)}.cards-container.svelte-pwex1j{display:grid;grid-gap:20px;height:100%;width:100%;min-height:0}");
}
function create_fragment5(ctx) {
  let div2;
  let div0;
  let t;
  let div1;
  let mounted;
  let dispose;
  return {
    c() {
      div2 = element("div");
      div0 = element("div");
      t = space();
      div1 = element("div");
      attr(div0, "class", "card-view-background svelte-pwex1j");
      attr(div1, "class", "cards-container svelte-pwex1j");
      attr(div2, "class", "card-view-container svelte-pwex1j");
    },
    m(target, anchor) {
      insert(target, div2, anchor);
      append(div2, div0);
      append(div2, t);
      append(div2, div1);
      ctx[10](div1);
      if (!mounted) {
        dispose = listen(
          div0,
          "click",
          /*click_handler*/
          ctx[9]
        );
        mounted = true;
      }
    },
    p: noop,
    i: noop,
    o: noop,
    d(detaching) {
      if (detaching) {
        detach(div2);
      }
      ctx[10](null);
      mounted = false;
      dispose();
    }
  };
}
function cardsPerPage(layout) {
  if (!checkLayout(layout))
    return 0;
  return layout[0] * layout[1];
}
function setLayout(contentEl, layout) {
  if (!contentEl)
    return;
  if (!checkLayout(layout))
    return;
  contentEl.style.gridTemplateColumns = `repeat(${layout[1]}, minmax(0, 1fr))`;
  contentEl.style.gridTemplateRows = `repeat(${layout[0]}, 1fr)`;
}
function checkLayout(layout) {
  const check = (x) => Number.isInteger(x) && x > 0;
  return check(layout[0]) && check(layout[1]);
}
function instance5($$self, $$props, $$invalidate) {
  let { layout } = $$props;
  let { focusEl } = $$props;
  let contentEl;
  let cards = [];
  const dispatcher = createEventDispatcher();
  function addCard(file) {
    if (!contentEl)
      return;
    if (!focusEl)
      return;
    if (cards.length >= cardsPerPage(layout))
      return;
    const card = new CardContainer_default({
      target: contentEl,
      props: {
        file,
        id: cards.length,
        selected: false,
        focusEl
      }
    });
    cards.push(card);
  }
  function renderPage(files) {
    files.forEach((file) => {
      addCard(file);
    });
  }
  function focusOn(id) {
    const pos = id % cardsPerPage(layout);
    [-1, 0, 1].forEach((i) => {
      const card = cards[pos + i];
      if (!card)
        return;
      if (i === 0) {
        card.$set({ selected: true });
      } else {
        card.$set({ selected: false });
      }
    });
  }
  function detachCards() {
    cards.forEach((card) => {
      card.$destroy();
    });
    cards = [];
  }
  function checkCardsRenderedCorrectly(files) {
    if (!checkLayout(layout))
      return false;
    for (let i = 0; i < cardsPerPage(layout); i++) {
      const file = files[i];
      const card = cards[i];
      if (file?.path !== card?.path()) {
        return false;
      }
    }
    return true;
  }
  onMount(() => {
    setLayout(contentEl, layout);
  });
  onDestroy(() => {
    detachCards();
  });
  const click_handler = () => {
    dispatcher("should-destroy");
  };
  function div1_binding($$value) {
    binding_callbacks[$$value ? "unshift" : "push"](() => {
      contentEl = $$value;
      $$invalidate(0, contentEl);
    });
  }
  $$self.$$set = ($$props2) => {
    if ("layout" in $$props2)
      $$invalidate(2, layout = $$props2.layout);
    if ("focusEl" in $$props2)
      $$invalidate(3, focusEl = $$props2.focusEl);
  };
  return [
    contentEl,
    dispatcher,
    layout,
    focusEl,
    addCard,
    renderPage,
    focusOn,
    detachCards,
    checkCardsRenderedCorrectly,
    click_handler,
    div1_binding
  ];
}
var CardViewComponent = class extends SvelteComponent {
  constructor(options) {
    super();
    init(
      this,
      options,
      instance5,
      create_fragment5,
      safe_not_equal,
      {
        layout: 2,
        focusEl: 3,
        addCard: 4,
        renderPage: 5,
        focusOn: 6,
        detachCards: 7,
        checkCardsRenderedCorrectly: 8
      },
      add_css5
    );
  }
  get addCard() {
    return this.$$.ctx[4];
  }
  get renderPage() {
    return this.$$.ctx[5];
  }
  get focusOn() {
    return this.$$.ctx[6];
  }
  get detachCards() {
    return this.$$.ctx[7];
  }
  get checkCardsRenderedCorrectly() {
    return this.$$.ctx[8];
  }
};
var CardViewComponent_default = CardViewComponent;

// src/ui/Outline.svelte
function add_css6(target) {
  append_styles(target, "svelte-f5i2qg", ".outline-container.svelte-f5i2qg{position:absolute;top:0;left:0;width:100%;height:100%;z-index:var(--layer-modal);pointer-events:none}");
}
function create_fragment6(ctx) {
  let div;
  return {
    c() {
      div = element("div");
      attr(div, "class", "outline-container svelte-f5i2qg");
    },
    m(target, anchor) {
      insert(target, div, anchor);
      ctx[2](div);
    },
    p: noop,
    i: noop,
    o: noop,
    d(detaching) {
      if (detaching) {
        detach(div);
      }
      ctx[2](null);
    }
  };
}
var STYLE_VAR_COLOR_SEARCH_MODE_OUTLINE = "--search-mode-outline";
function instance6($$self, $$props, $$invalidate) {
  let { lineWidth } = $$props;
  let el;
  onMount(() => {
    if (!el)
      return;
    $$invalidate(0, el.style.outline = `${lineWidth}px solid var(${STYLE_VAR_COLOR_SEARCH_MODE_OUTLINE})`, el);
    $$invalidate(0, el.style.outlineOffset = `-${lineWidth}px`, el);
  });
  function div_binding($$value) {
    binding_callbacks[$$value ? "unshift" : "push"](() => {
      el = $$value;
      $$invalidate(0, el);
    });
  }
  $$self.$$set = ($$props2) => {
    if ("lineWidth" in $$props2)
      $$invalidate(1, lineWidth = $$props2.lineWidth);
  };
  return [el, lineWidth, div_binding];
}
var Outline = class extends SvelteComponent {
  constructor(options) {
    super();
    init(this, options, instance6, create_fragment6, safe_not_equal, { lineWidth: 1 }, add_css6);
  }
};
var Outline_default = Outline;

// src/ui/WorkspacePreview.svelte
function add_css7(target) {
  append_styles(target, "svelte-1fata0e", ".core-search-assistant_workspace-preview_container.svelte-1fata0e{position:absolute;top:0;left:0;width:100%;height:100%;z-index:var(--layer-modal);background-color:var(--background-primary);padding:20px 30px;overflow:auto}.core-search-assistant_workspace-preview_container.svelte-1fata0e .highlight-search-match{color:var(--highlight-search-match);background-color:var(--highlight-search-match-bg)}.core-search-assistant_workspace-preview_container.svelte-1fata0e .focus-search-match{background-color:var(--focus-search-match-bg)}.core-search-assistant_workspace-preview_container.svelte-1fata0e .workspace-leaf{contain:initial !important;height:100%}.core-search-assistant_workspace-preview_container.svelte-1fata0e .workspace-leaf-resize-handle{display:none}.core-search-assistant_workspace-preview_container.svelte-1fata0e .view-header{display:none}.core-search-assistant_workspace-preview_container.svelte-1fata0e .view-content{overflow:hidden}.core-search-assistant_workspace-preview_container.svelte-1fata0e .markdown-preview-view{padding:0}.core-search-assistant_workspace-preview_container.svelte-1fata0e .modal-content{margin:0}.core-search-assistant_workspace-preview_container.svelte-1fata0e .markdown-source-view.mod-cm6 .cm-editor{flex:initial;display:initial}.core-search-assistant_workspace-preview_container.svelte-1fata0e .markdown-source-view.mod-cm6{display:initial}.core-search-assistant_workspace-preview_container.svelte-1fata0e .markdown-source-view{pointer-events:none}.core-search-assistant_workspace-preview_container.svelte-1fata0e .markdown-source-view.mod-cm6 .cm-scroller{padding:0}");
}
function create_fragment7(ctx) {
  let div1;
  let div0;
  let t_value = `${/*file*/
  ctx[0].extension.toUpperCase()} file`;
  let t;
  return {
    c() {
      div1 = element("div");
      div0 = element("div");
      t = text(t_value);
      attr(div0, "class", "content-not-supported-file-format");
      attr(div1, "class", "core-search-assistant_workspace-preview_container svelte-1fata0e");
    },
    m(target, anchor) {
      insert(target, div1, anchor);
      append(div1, div0);
      append(div0, t);
      ctx[4](div1);
    },
    p(ctx2, [dirty]) {
      if (dirty & /*file*/
      1 && t_value !== (t_value = `${/*file*/
      ctx2[0].extension.toUpperCase()} file`))
        set_data(t, t_value);
    },
    i: noop,
    o: noop,
    d(detaching) {
      if (detaching) {
        detach(div1);
      }
      ctx[4](null);
    }
  };
}
function instance7($$self, $$props, $$invalidate) {
  let $app;
  component_subscribe($$self, app, ($$value) => $$invalidate(6, $app = $$value));
  let { file } = $$props;
  let { matches } = $$props;
  let { focusEl } = $$props;
  let containerEl;
  let renderer;
  onMount(async () => {
    if (!containerEl)
      return;
    const fileType = fileTypeMap[file.extension];
    if (fileType !== void 0) {
      containerEl.empty();
      renderer = await new ViewGenerator($app, containerEl, file).registerExtension(new ExcalidrawViewGeneratorExtension($app)).registerExtension(new KanbanViewGeneratorExtension($app)).registerExtension(new MarkdownViewGeneratorExtension()).registerExtension(new NonMarkdownViewGeneratorExtension()).load("source");
      highlightMatches();
    }
    focusEl?.focus();
  });
  onDestroy(() => {
    setTimeout(() => renderer?.unload(), 1e3);
  });
  function highlightMatches() {
    renderer?.highlightMatches(matches ?? [], "highlight-search-match");
  }
  function div1_binding($$value) {
    binding_callbacks[$$value ? "unshift" : "push"](() => {
      containerEl = $$value;
      $$invalidate(1, containerEl);
    });
  }
  $$self.$$set = ($$props2) => {
    if ("file" in $$props2)
      $$invalidate(0, file = $$props2.file);
    if ("matches" in $$props2)
      $$invalidate(2, matches = $$props2.matches);
    if ("focusEl" in $$props2)
      $$invalidate(3, focusEl = $$props2.focusEl);
  };
  return [file, containerEl, matches, focusEl, div1_binding];
}
var WorkspacePreview = class extends SvelteComponent {
  constructor(options) {
    super();
    init(this, options, instance7, create_fragment7, safe_not_equal, { file: 0, matches: 2, focusEl: 3 }, add_css7);
  }
};
var WorkspacePreview_default = WorkspacePreview;

// src/Controller.ts
var DELAY_TO_RELOAD_IN_MILLISECOND = 1e3;
var RETRY_INTERVAL = 1;
var RETRY_TRIALS = 1e3;
var DELAY_TO_RENDER_CARD_VIEW_ON_ENTRY_IN_MILLISECOND = 100;
var Controller = class extends obsidian.Component {
  constructor(app2, plugin2, events, searchInterface) {
    super();
    this.app = app2;
    this.plugin = plugin2;
    this.events = events;
    this.searchInterface = searchInterface;
    this.modeScope = new ModeScope();
    this.cardViewCheckDebouncer = (0, import_obsidian14.debounce)(
      this.onCheckCardView,
      DELAY_TO_RELOAD_IN_MILLISECOND,
      true
    );
    this.countSearchItemDetected = 0;
  }
  onunload() {
    this.exit();
  }
  onload() {
    this.saveLayout();
    this.setSearchModeTriggers();
  }
  async enter() {
    if (this.modeScope.inSearchMode) {
      return;
    }
    this.setHotkeys();
    this.addChildren();
    if (this.plugin.settings?.autoToggleSidebar) {
      this.collapseOppositeSidedock();
    }
    const shouldDetectSearchItems = this.plugin.settings?.autoPreviewMode === "cardView" && this.plugin.settings.renderCardsManually === false;
    if (shouldDetectSearchItems) {
      this.searchInterface.startWatching(this.events);
      await delay(DELAY_TO_RENDER_CARD_VIEW_ON_ENTRY_IN_MILLISECOND);
      this.renewCardViewPage();
      this.cardViewCheckDebouncer();
    }
    this.modeScope.push();
  }
  reset() {
    if (!this.modeScope.inSearchMode) {
      return;
    }
    this.forget();
    this.unfocus();
    this.cardViewComponent?.detachCards();
    this.countSearchItemDetected = 0;
  }
  exit(reason) {
    if (!this.modeScope.inSearchMode) {
      return;
    }
    this.reset();
    this.detachHotkeys();
    this.removeChildren();
    if (this.shouldCollapseSidedock(reason)) {
      this.collapseSidedock();
    }
    if (this.plugin.settings?.autoToggleSidebar) {
      this.restoreOppositeSidedock();
    }
    this.countSearchItemDetected = 0;
    this.searchInterface.stopWatching();
    this.unfocus();
    this.modeScope.reset();
  }
  focus() {
    if (this.currentFocusId === void 0) {
      return;
    }
    this.searchInterface.focusOn(this.currentFocusId);
    this.cardViewComponent?.focusOn(this.currentFocusId);
  }
  open(direction) {
    if (this.currentFocusId === void 0) {
      return;
    }
    this.searchInterface.open(this.currentFocusId, direction);
  }
  async renewCardViewPage() {
    if (this.plugin.settings?.autoPreviewMode !== "cardView")
      return;
    this.cardViewComponent?.detachCards();
    this.cardViewComponent?.renderPage(this.filesToBeRendered());
    if (this.currentFocusId !== void 0) {
      this.cardViewComponent?.focusOn(this.currentFocusId ?? 0);
    }
  }
  filesToBeRendered() {
    const cardsPerPage2 = this.cardsPerPage();
    if (cardsPerPage2 === void 0) {
      return [];
    }
    const pageId = Math.floor((this.currentFocusId ?? 0) / cardsPerPage2);
    const items = this.plugin.searchInterface?.resultItems;
    if (!items)
      return [];
    return items.slice(pageId * cardsPerPage2).map((item) => item.file);
  }
  collapseSidedock() {
    this.searchInterface.collapseSidedock();
  }
  collapseOppositeSidedock() {
    const collapsed = this.searchInterface.oppositeSidedock?.collapsed;
    this.searchInterface.collapseOppositeSidedock();
    this._restoreOppositeSidedock = () => {
      if (collapsed === false) {
        this.searchInterface.expandOppositeSidedock();
      }
    };
  }
  restoreOppositeSidedock() {
    const restoreOppositeSidedock = this._restoreOppositeSidedock;
    if (restoreOppositeSidedock === void 0) {
      return void 0;
    }
    return restoreOppositeSidedock();
  }
  addChildren() {
    this.removeChildren();
    const { settings } = this.plugin;
    if (settings === void 0) {
      throw "[ERROR in Core Search Assistant] failed to addChildren: failed to read setting";
    }
    this.outline = new Outline_default({
      target: document.body,
      props: {
        lineWidth: settings.outlineWidth
      }
    });
    if (settings.autoPreviewMode === "cardView") {
      this.renewCardViewComponent();
    }
  }
  removeChildren() {
    this.outline?.$destroy();
    this.outline = void 0;
    this.cardViewComponent?.$destroy();
    this.cardViewComponent = void 0;
    this.workspacePreviewComponent?.$destroy();
    this.workspacePreviewComponent = void 0;
  }
  forget() {
    this.currentFocusId = void 0;
    this.countSearchItemDetected = 0;
  }
  navigateForward() {
    let updated = true;
    const numResults = this.searchInterface.count() ?? 0;
    if (this.currentFocusId === void 0) {
      this.currentFocusId = 0;
    } else {
      this.currentFocusId++;
      if (this.currentFocusId >= numResults) {
        this.currentFocusId = numResults - 1;
        updated = false;
      }
    }
    if (!updated)
      return;
    const { settings } = this.plugin;
    if (!settings)
      return;
    if (settings.autoPreviewMode === "cardView" && this.shouldTransitNextPageInCardView()) {
      this.renewCardViewPage();
    } else if (settings.autoPreviewMode === "singleView") {
      this.renewWorkspacePreviewComponent();
    }
    this.focus();
  }
  navigateBack() {
    if (this.currentFocusId === void 0) {
      return;
    }
    let updated = true;
    this.currentFocusId--;
    if (this.currentFocusId < 0) {
      this.currentFocusId = 0;
      updated = false;
    }
    if (!updated)
      return;
    const { settings } = this.plugin;
    if (!settings)
      return;
    if (settings.autoPreviewMode === "cardView" && this.shouldTransitPreviousPageInCardView()) {
      this.renewCardViewPage();
    } else if (settings.autoPreviewMode === "singleView") {
      this.renewWorkspacePreviewComponent();
    }
    this.focus();
  }
  moveToNextPage() {
    const pageId = this.pageId;
    if (pageId === void 0)
      return;
    const pageCount = this.pageCount;
    if (pageCount === void 0)
      return;
    if (pageId >= pageCount - 1)
      return;
    const cardsPerPage2 = this.cardsPerPage();
    if (cardsPerPage2 === void 0)
      return;
    this.currentFocusId = cardsPerPage2 * (pageId + 1);
    this.renewCardViewPage();
    this.focus();
  }
  moveToPreviousPage() {
    const pageId = this.pageId;
    if (pageId === void 0)
      return;
    const pageCount = this.pageCount;
    if (pageCount === void 0)
      return;
    if (pageId <= 0)
      return;
    const cardsPerPage2 = this.cardsPerPage();
    if (cardsPerPage2 === void 0)
      return;
    this.currentFocusId = cardsPerPage2 * (pageId - 1);
    this.renewCardViewPage();
    this.focus();
  }
  unfocus() {
    this.searchInterface.unfocus();
  }
  openPreviewModal() {
    const { currentFocusId } = this;
    if (currentFocusId === void 0) {
      return;
    }
    const item = this.searchInterface.getResultItemAt(currentFocusId);
    if (!item) {
      return;
    }
    new PreviewModal(this.app, this.plugin, this.modeScope, item).open();
  }
  shouldTransitNextPageInCardView() {
    if (this.currentFocusId === void 0 || this.currentFocusId === 0) {
      return false;
    }
    if (!this.plugin.settings) {
      return false;
    }
    const [row, column] = parseCardLayout(this.plugin.settings.cardViewLayout);
    const cardsPerPage2 = row * column;
    return this.currentFocusId % cardsPerPage2 === 0;
  }
  shouldTransitPreviousPageInCardView() {
    if (!this.plugin.settings) {
      return false;
    }
    const [row, column] = parseCardLayout(this.plugin.settings.cardViewLayout);
    const cardsPerPage2 = row * column;
    if (this.currentFocusId === void 0) {
      return false;
    }
    return (this.currentFocusId + 1) % cardsPerPage2 === 0;
  }
  get pageId() {
    if (this.currentFocusId === void 0)
      return void 0;
    const cardsPerPage2 = this.cardsPerPage();
    if (cardsPerPage2 === void 0)
      return void 0;
    const pageId = Math.floor(this.currentFocusId / cardsPerPage2);
    return pageId;
  }
  get pageCount() {
    const numResults = this.plugin.searchInterface?.count();
    const cardsPerPage2 = this.cardsPerPage();
    if (cardsPerPage2 === void 0)
      return void 0;
    const pageCount = Math.ceil((numResults ?? 0) / cardsPerPage2);
    return pageCount;
  }
  cardsPerPage() {
    if (!this.plugin.settings) {
      return void 0;
    }
    const [row, column] = parseCardLayout(this.plugin.settings.cardViewLayout);
    return row * column;
  }
  /**
   * check layout change
   * use for detecting whether layout-change really occurs
   * @returns callback which returns
   */
  saveLayout() {
    this.app.workspace.onLayoutReady(async () => {
      const inputEl = await retry(
        () => this.searchInterface.searchInputEl,
        RETRY_INTERVAL,
        RETRY_TRIALS
      );
      this._layoutChanged = async () => inputEl !== await retry(
        () => this.searchInterface.searchInputEl,
        RETRY_INTERVAL,
        RETRY_TRIALS
      );
    });
  }
  async layoutChanged() {
    const shouldRenewController = await this._layoutChanged?.();
    if (shouldRenewController === void 0) {
      throw "[ERROR in Core Search Assistant] failed to renewRequired: saveLayout was not called.";
    }
    return shouldRenewController;
  }
  setSearchModeTriggers() {
    this.registerEvent(
      this.events.on(
        EVENT_SEARCH_RESULT_ITEM_DETECTED,
        this.onSearchResultItemDetected
      )
    );
    this.registerEvent(
      this.events.on(EVENT_SORT_ORDER_CHANGED, this.onSortOrderChanged)
    );
    this.app.workspace.onLayoutReady(async () => {
      const appContainerEl = await retry(
        () => this.app.dom.appContainerEl,
        RETRY_INTERVAL,
        RETRY_TRIALS
      );
      if (appContainerEl === void 0) {
        throw "[ERROR in Core Search Assistant] failed to find the app container element";
      }
      const inputEl = await retry(
        () => this.plugin.searchInterface?.searchInputEl,
        RETRY_INTERVAL,
        RETRY_TRIALS
      );
      if (inputEl === void 0) {
        throw "[ERROR in Core Search Assistant] failed to find the search input form.";
      }
      const matchingCaseButtonEl = await retry(
        () => this.plugin.searchInterface?.matchingCaseButtonEl,
        RETRY_INTERVAL,
        RETRY_TRIALS
      );
      if (matchingCaseButtonEl === void 0) {
        throw "[ERROR in Core Search Assistant] failed to find the matching case button.";
      }
      this.registerDomEvent(appContainerEl, "click", (evt) => {
        const targetEl = evt.target;
        if (!(targetEl instanceof HTMLElement)) {
          return;
        }
        if (this.plugin.searchInterface?.searchLeaf?.containerEl.contains(
          targetEl
        )) {
          if (!this.plugin.searchInterface.isBuiltInElementToOpenFile(targetEl))
            return;
        }
        if (this.plugin.searchInterface?.tabHeaderEl?.contains(targetEl)) {
          return;
        }
        if (this.plugin.searchInterface?.isShowMoreContextButton(targetEl)) {
          return;
        }
        if (this.modeScope.depth === 1) {
          this.exit({ id: "mouse", event: evt });
        }
      });
      this.registerDomEvent(matchingCaseButtonEl, "click", () => {
        if (this.modeScope.inSearchMode) {
          this.reset();
        }
      });
      this.registerDomEvent(inputEl, "input", () => {
        if (!this.modeScope.inSearchMode) {
          this.enter();
        }
        this.reset();
      });
      this.registerDomEvent(inputEl, "keypress", (evt) => {
        if (evt.key !== "Enter") {
          return;
        }
        if (!this.modeScope.inSearchMode) {
          this.enter();
        }
        this.reset();
      });
      this.registerDomEvent(inputEl, "focus", () => {
        if (!this.modeScope.inSearchMode) {
          this.enter();
        }
      });
    });
  }
  setHotkeys() {
    const hotkeyMap = this.plugin.settings?.searchModeHotkeys;
    if (!hotkeyMap)
      return;
    const scope = new obsidian.Scope();
    this.app.keymap.pushScope(scope);
    hotkeyMap.selectNext.forEach((hotkey) => {
      scope.register(hotkey.modifiers, hotkey.key, (evt) => {
        evt.preventDefault();
        this.navigateForward();
      });
    });
    hotkeyMap.selectPrevious.forEach((hotkey) => {
      scope.register(hotkey.modifiers, hotkey.key, (evt) => {
        evt.preventDefault();
        this.navigateBack();
      });
    });
    hotkeyMap.open.forEach((hotkey) => {
      scope.register(hotkey.modifiers, hotkey.key, (evt) => {
        evt.preventDefault();
        this.open();
        this.exit();
      });
    });
    hotkeyMap.openInNewPane.forEach((hotkey) => {
      scope.register(hotkey.modifiers, hotkey.key, (evt) => {
        evt.preventDefault();
        this.open(this.plugin.settings?.splitDirection);
        this.exit();
      });
    });
    hotkeyMap.previewModal.forEach((hotkey) => {
      scope.register(hotkey.modifiers, hotkey.key, () => {
        if (this.app.vault.config.legacyEditor) {
          return;
        }
        this.openPreviewModal();
      });
    });
    hotkeyMap.showOptions.forEach((hotkey) => {
      scope.register(hotkey.modifiers, hotkey.key, () => {
        new OptionModal(this.app, this.plugin, this.modeScope).open();
      });
    });
    hotkeyMap.nextPage.forEach((hotkey) => {
      scope.register(hotkey.modifiers, hotkey.key, () => {
        if (this.plugin.settings?.autoPreviewMode === "cardView") {
          this.moveToNextPage();
        }
      });
    });
    hotkeyMap.previousPage.forEach((hotkey) => {
      scope.register(hotkey.modifiers, hotkey.key, () => {
        if (this.plugin.settings?.autoPreviewMode === "cardView") {
          this.moveToPreviousPage();
        }
      });
    });
    hotkeyMap.copyLink.forEach((hotkey) => {
      scope.register(hotkey.modifiers, hotkey.key, () => {
        const item = this.searchInterface.getResultItemAt(
          this.currentFocusId ?? 0
        );
        if (!item)
          return;
        const { file } = item;
        const internalLink = generateInternalLinkFrom(this.app, file);
        navigator.clipboard.writeText(internalLink);
        new import_obsidian14.Notice("Copy wiki link!");
      });
    });
    scope.register([], "Escape", (evt) => {
      evt.preventDefault();
      this.exit();
    });
    scope.register([], "Enter", (evt) => {
      setTimeout(this.focusOnInput, 100);
      const shouldRenderCardsManually = this.plugin.settings?.autoPreviewMode === "cardView" && this.plugin.settings.renderCardsManually;
      if (shouldRenderCardsManually) {
        evt.preventDefault();
        this.reset();
        this.renewCardViewPage();
      }
    });
    this._detachHotkeys = () => {
      this.app.keymap.popScope(scope);
    };
  }
  detachHotkeys() {
    const detachHotkeys = this._detachHotkeys;
    if (detachHotkeys === void 0) {
      return;
    }
    detachHotkeys();
  }
  get onSearchResultItemDetected() {
    return () => {
      if (this.plugin.settings?.autoPreviewMode !== "cardView") {
        return;
      }
      if (this.currentFocusId !== void 0) {
        return;
      }
      if (this.countSearchItemDetected === 0) {
        this.cardViewComponent?.detachCards();
      }
      const item = this.searchInterface.getResultItemAt(
        this.countSearchItemDetected
      );
      if (!item)
        return;
      this.cardViewComponent?.addCard(item.file);
      this.cardViewCheckDebouncer();
      this.countSearchItemDetected++;
    };
  }
  renewCardViewComponent() {
    this.cardViewComponent?.$destroy();
    const { settings } = this.plugin;
    if (!settings)
      return;
    const focusEl = this.searchInterface.searchInputEl;
    if (!focusEl)
      return;
    const layout = parseCardLayout(settings.cardViewLayout);
    this.app.workspace.onLayoutReady(() => {
      const containerEl = this.app.workspace.rootSplit.containerEl;
      const cardViewComponent = new CardViewComponent_default({
        target: containerEl,
        props: {
          layout,
          focusEl
        }
      });
      this.cardViewComponent = cardViewComponent;
    });
  }
  renewWorkspacePreviewComponent() {
    this.workspacePreviewComponent?.$destroy();
    if (this.currentFocusId === void 0)
      return;
    const focusEl = this.searchInterface.searchInputEl;
    if (!focusEl)
      return;
    const item = this.searchInterface.getResultItemAt(this.currentFocusId);
    if (!item)
      return;
    this.app.workspace.onLayoutReady(() => {
      const containerEl = this.app.workspace.rootSplit.containerEl;
      const workspacePreviewComponent = new WorkspacePreview_default({
        target: containerEl,
        props: {
          file: item.file,
          matches: item.result.content ?? [],
          focusEl
        }
      });
      this.workspacePreviewComponent = workspacePreviewComponent;
    });
  }
  get focusOnInput() {
    return async () => {
      const inputEl = await retry(
        () => this.plugin.searchInterface?.searchInputEl,
        RETRY_INTERVAL,
        RETRY_TRIALS
      );
      if (inputEl === void 0) {
        throw "[ERROR in Core Search Assistant] failed to find the search input form.";
      }
      inputEl.focus();
    };
  }
  get onSortOrderChanged() {
    return () => {
      this.reset();
      if (this.plugin.settings?.autoPreviewMode === "cardView") {
        this.renewCardViewPage();
      }
    };
  }
  shouldCollapseSidedock(reason) {
    if (!this.plugin.settings?.autoToggleSidebar) {
      return false;
    }
    if (reason === void 0) {
      return true;
    }
    if (reason.id !== "mouse") {
      return true;
    }
    const targetEl = reason.event.target;
    if (!(targetEl instanceof HTMLElement)) {
      return true;
    }
    return !this.searchInterface.sideDock?.containerEl.contains(targetEl);
  }
  get onCheckCardView() {
    return () => {
      const { cardViewComponent } = this;
      if (!cardViewComponent)
        return;
      const ok = cardViewComponent.checkCardsRenderedCorrectly(
        this.filesToBeRendered()
      );
      if (!ok) {
        this.reset();
        this.renewCardViewPage();
      }
    };
  }
};

// src/interfaces/SearchComponentInterface.ts
var import_obsidian16 = require("obsidian");

// src/types/Guards.ts
var import_obsidian15 = require("obsidian");
var SORT_ORDER_IN_SEARCH = [
  "alphabeticalReverse",
  "alphabetical",
  "byModifiedTime",
  "byModifiedTimeReverse",
  "byCreatedTime",
  "byCreatedTimeReverse"
];
function isSearchView(view) {
  if (typeof view !== "object") {
    return false;
  }
  if (view === null) {
    return false;
  }
  const {
    matchingCase,
    explainSearch,
    dom,
    setCollapseAll,
    setExplainSearch,
    setExtraContext,
    setMatchingCase,
    setSortOrder,
    searchInfoEl,
    searchComponent
  } = view;
  if (typeof matchingCase !== "boolean") {
    return false;
  }
  if (typeof explainSearch !== "boolean") {
    return false;
  }
  if (!isSearchDom(dom)) {
    return false;
  }
  if (typeof searchComponent !== "object") {
    return false;
  }
  if (typeof searchInfoEl !== "object") {
    return false;
  }
  if (!(searchInfoEl instanceof HTMLDivElement)) {
    return false;
  }
  if (!(setCollapseAll instanceof Function)) {
    return false;
  }
  if (!(setExplainSearch instanceof Function)) {
    return false;
  }
  if (!(setExtraContext instanceof Function)) {
    return false;
  }
  if (!(setMatchingCase instanceof Function)) {
    return false;
  }
  if (!(setSortOrder instanceof Function)) {
    return false;
  }
  return true;
}
function isSearchDom(obj) {
  if (typeof obj !== "object") {
    return false;
  }
  if (obj === null) {
    return false;
  }
  const { extraContext, collapseAll, sortOrder, vChildren, childrenEl } = obj;
  if (typeof extraContext !== "boolean") {
    return false;
  }
  if (typeof collapseAll !== "boolean") {
    return false;
  }
  if (typeof sortOrder !== "string") {
    return false;
  }
  if (!SORT_ORDER_IN_SEARCH.includes(sortOrder)) {
    return false;
  }
  if (!isSearchResultItemGroup(vChildren)) {
    return false;
  }
  if (typeof childrenEl !== "object") {
    return false;
  }
  if (!(childrenEl instanceof HTMLElement)) {
    return false;
  }
  return true;
}
function isSearchResultItemGroup(obj) {
  if (typeof obj !== "object" || obj === null) {
    return false;
  }
  const { _children: children2 } = obj;
  if (typeof children2 !== "object") {
    return false;
  }
  if (!Array.isArray(children2)) {
    return false;
  }
  for (const child of children2) {
    if (!isSearchResultItem(child)) {
      return false;
    }
  }
  return true;
}
function isSearchResultItem(obj) {
  if (typeof obj !== "object" || obj === null) {
    return false;
  }
  const { file, containerEl } = obj;
  if (!(file instanceof import_obsidian15.TFile)) {
    return false;
  }
  if (!(containerEl instanceof HTMLElement)) {
    return false;
  }
  return true;
}

// src/utils/LinkedList.ts
var LinkedList = class {
  constructor(events, eventId) {
    this.unlinkedPool = /* @__PURE__ */ new Map();
    this.events = events;
    this.eventId = eventId;
  }
  // attach nodes recursively
  structure(cur, pre) {
    let linked = false;
    if (pre === void 0) {
      this.setRoot(cur);
      linked = true;
      this.signal();
    } else if (this.tail !== void 0 && pre === this.tail.entity) {
      this.link(cur);
      linked = true;
      this.unlinkedPool.delete(cur);
      this.signal();
    }
    if (linked) {
      if (!this.unlinkedPool.has(cur)) {
        return;
      }
      const next = this.unlinkedPool.get(cur);
      if (next === void 0) {
        return;
      }
      this.structure(next, cur);
    } else {
      if (pre) {
        this.unlinkedPool.set(pre, cur);
      }
    }
  }
  setRoot(entity) {
    const rootNode = {
      entity,
      pre: void 0,
      next: void 0
    };
    this.head = rootNode;
    this.tail = rootNode;
  }
  link(cur) {
    if (!this.tail) {
      return;
    }
    const currentTail = this.tail;
    currentTail.next = {
      entity: cur,
      pre: currentTail,
      next: void 0
    };
    this.tail = currentTail.next;
  }
  clean() {
    this.head = void 0;
    this.tail = void 0;
    this.unlinkedPool = /* @__PURE__ */ new Map();
  }
  // let outside know a node is attached
  signal() {
    this.events.trigger(this.eventId);
  }
};

// src/interfaces/SearchComponentInterface.ts
var SearchComponentInterface = class extends import_obsidian16.Component {
  constructor(app2, plugin2, events) {
    super();
    this.observationConfig = {
      childList: true
    };
    this.onObservedCallback = async (mutations, _observer) => {
      for (const mutation of mutations) {
        if (mutation.addedNodes.length === 0) {
          continue;
        }
        const pre = mutation.previousSibling;
        if (!(pre instanceof HTMLElement)) {
          continue;
        }
        for (const node of Array.from(mutation.addedNodes)) {
          if (!(node instanceof HTMLElement)) {
            continue;
          }
          const isSearchResultItem2 = node.tagName === "DIV" && node.hasClass("tree-item") && node.hasClass("search-result");
          if (!isSearchResultItem2) {
            continue;
          }
          if (!this.linkedList) {
            return;
          }
          this.linkedList.structure(
            node,
            this.isRootSearchResult(pre) ? void 0 : pre
          );
        }
      }
    };
    this.app = app2;
    this.plugin = plugin2;
    this.events = events;
    this.observer = new MutationObserver(
      this.onObservedCallback.bind(this)
    );
  }
  onload() {
    this.app.workspace.onLayoutReady(() => {
      this.renewSortOrderInfo();
      this.registerDomEvent(document, "click", () => {
        this.renewSortOrderInfo(this.events);
      });
    });
  }
  onunload() {
    this.sortOrderContainerEl?.empty();
    this.sortOrderContainerEl?.remove();
    this.observer.disconnect();
  }
  toggleMatchingCase() {
    const view = this.searchView;
    view?.setMatchingCase(!view.matchingCase);
  }
  toggleExplainSearch() {
    const view = this.searchView;
    view?.setExplainSearch(!view.explainSearch);
  }
  toggleCollapseAll() {
    const view = this.searchView;
    view?.setCollapseAll(!view.dom.collapseAll);
  }
  toggleExtraContext() {
    const view = this.searchView;
    view?.setExtraContext(!view.dom.extraContext);
  }
  setSortOrder(sortOrder) {
    const view = this.searchView;
    const originalOrder = view?.dom.sortOrder;
    view?.setSortOrder(sortOrder);
    return sortOrder !== originalOrder;
  }
  focusOn(pos) {
    this.unfocus();
    const item = this.getResultItemAt(pos);
    if (!item) {
      return;
    }
    item.containerEl.addClass(
      "core-search-assistant_search-result-items-focus"
    );
    item.containerEl.scrollIntoView(
      this.plugin.settings?.keepSelectedItemsCentered ? { block: "center" } : { block: "nearest" }
    );
  }
  unfocus() {
    const items = this.resultItems;
    items.forEach((item) => {
      item.containerEl.removeClass(
        "core-search-assistant_search-result-items-focus"
      );
    });
  }
  async open(pos, direction) {
    const item = this.getResultItemAt(pos);
    if (!item) {
      return;
    }
    const { file } = item;
    const leaf = direction === void 0 ? this.app.workspace.getMostRecentLeaf() : this.app.workspace.splitActiveLeaf(direction);
    await leaf.openFile(file);
    this.app.workspace.setActiveLeaf(leaf, true, true);
  }
  renewSortOrderInfo(events) {
    if (!this.sortOrderContainerEl) {
      this.createSortOrderEls();
    }
    const view = this.searchView;
    if (!view) {
      return;
    }
    const sortOrder = view.dom.sortOrder;
    if (!this.sortOrderContentEl) {
      return;
    }
    const originalContent = this.sortOrderContentEl.textContent;
    this.sortOrderContentEl.textContent = searchOptions[sortOrder].description;
    if (events !== void 0 && originalContent !== this.sortOrderContentEl.textContent) {
      events.trigger(EVENT_SORT_ORDER_CHANGED);
    }
  }
  count() {
    const results = this.searchView?.dom.vChildren._children;
    if (!results) {
      return 0;
    }
    return results.length;
  }
  get resultItems() {
    return this.searchView?.dom.vChildren._children ?? [];
  }
  getResultItemAt(pos) {
    return this.searchView?.dom.vChildren._children[pos];
  }
  get searchInputEl() {
    return this.searchView?.searchComponent.inputEl;
  }
  startWatching(events) {
    this.linkedList = new LinkedList(
      events,
      EVENT_SEARCH_RESULT_ITEM_DETECTED
    );
    const childrenContainerEl = this.searchView?.dom.childrenEl;
    if (!(childrenContainerEl instanceof HTMLElement)) {
      throw "[ERROR in Core Search Assistant] failed to SearchComponentInterface#startWatching: childrenContainerEl is not an instance of HTMLElement";
    }
    this.observer.observe(childrenContainerEl, this.observationConfig);
  }
  stopWatching() {
    this.observer.disconnect();
  }
  collapseOppositeSidedock() {
    const sideDock = this.oppositeSidedock;
    if (sideDock === void 0) {
      throw "[ERROR in Core Search Assistant] failed to collapseOppositeSidedock: failed to fetch the opposite sidedock";
    }
    sideDock.collapse();
  }
  expandOppositeSidedock() {
    const sideDock = this.oppositeSidedock;
    if (sideDock === void 0) {
      throw "[ERROR in Core Search Assistant] failed to expandOppositeSidedock: failed to fetch the opposite sidedock";
    }
    sideDock.expand();
  }
  collapseSidedock() {
    const sideDock = this.sideDock;
    if (sideDock === void 0) {
      throw "[ERROR in Core Search Assistant] failed to collapseSidedock: failed to fetch the sidedock";
    }
    sideDock.collapse();
  }
  get sideDock() {
    const leaf = this.searchLeaf;
    if (leaf === void 0) {
      return void 0;
    }
    const parent = leaf.getRoot();
    if (parent instanceof import_obsidian16.WorkspaceSidedock) {
      return parent;
    }
    return void 0;
  }
  get oppositeSidedock() {
    const leaf = this.searchLeaf;
    if (leaf === void 0) {
      return void 0;
    }
    const parent = leaf.getRoot();
    if (parent === this.app.workspace.leftSplit) {
      const opposite = this.app.workspace.rightSplit;
      return opposite instanceof import_obsidian16.WorkspaceSidedock ? opposite : void 0;
    }
    if (parent === this.app.workspace.rightSplit) {
      const opposite = this.app.workspace.leftSplit;
      return opposite instanceof import_obsidian16.WorkspaceSidedock ? opposite : void 0;
    }
    return void 0;
  }
  createSortOrderEls() {
    this.sortOrderContainerEl = createEl("div", {
      cls: "search-info-container"
    });
    this.sortOrderContentEl = this.sortOrderContainerEl.createEl("div");
    const view = this.searchView;
    if (!view) {
      return;
    }
    this.sortOrderContainerEl.insertAfter(view.searchInfoEl);
  }
  get matchingCaseButtonEl() {
    return this.searchView?.matchingCaseButtonEl;
  }
  get tabHeaderEl() {
    return this.searchLeaf?.tabHeaderEl;
  }
  isBuiltInElementToOpenFile(el) {
    const isFileNameContainerEl = el.tagName === "DIV" && el.hasClass("tree-item-inner");
    const isMatchCountContainerEl = el.tagName === "DIV" && el.hasClass("tree-item-flair-outer");
    const isMatchContainerEl = el.tagName === "DIV" && el.hasClass("search-result-file-match");
    if (isFileNameContainerEl || isMatchContainerEl || isMatchCountContainerEl) {
      return true;
    }
    const parentEl = el.parentElement;
    if (parentEl === null) {
      return false;
    }
    return this.isBuiltInElementToOpenFile(parentEl);
  }
  isShowMoreContextButton(el) {
    return el.tagName === "DIV" && el.hasClass("search-result-hover-button");
  }
  // get changeSortOrderButtonEl(): HTMLElement | undefined {
  // 	const changeSortOrderButtonEl =
  // 		this.searchView?.headerDom.navButtonsEl.querySelector(
  // 			'div.nav-action-button[aria-label="Change sort order"]'
  // 		);
  // 	return changeSortOrderButtonEl instanceof HTMLElement
  // 		? changeSortOrderButtonEl
  // 		: undefined;
  // }
  get searchView() {
    const leaf = this.searchLeaf;
    if (!leaf) {
      return void 0;
    }
    const view = leaf.view;
    return isSearchView(view) ? view : void 0;
  }
  get searchLeaf() {
    return this.app.workspace.getLeavesOfType("search")[0];
  }
  isRootSearchResult(el) {
    return el.tagName === "DIV" && !el.hasClass("tree-item") && !el.hasClass("search-result");
  }
  // async watchSortOrderChangeByClick() {
  // 	const callback = async (evt: Event) => {
  // 		this.renewSortOrderInfo();
  // 		if (evt.currentTarget === null) {
  // 			return;
  // 		}
  // 		evt.currentTarget.removeEventListener('click', callback);
  // 	};
  // 	await new Promise((resolve) => setTimeout(resolve, 1)); // prevent callback from being called immediately
  // 	document.addEventListener('click', callback);
  // }
  // getSortOrderSettingButton(): HTMLElement | undefined {
  // 	const view = this.getSearchView();
  // 	const buttonsEl = view?.headerDom.navButtonsEl;
  // 	if (!buttonsEl) {
  // 		return undefined;
  // 	}
  // 	const sortOrderSettingButtonEl = buttonsEl.querySelector(
  // 		'div.nav-action-button[aria-label="Change sort order"]'
  // 	);
  // 	return sortOrderSettingButtonEl
  // 		? (sortOrderSettingButtonEl as HTMLElement)
  // 		: undefined;
  // }
};

// src/main.ts
var import_obsidian17 = require("obsidian");
var CoreSearchAssistantPlugin = class extends import_obsidian17.Plugin {
  async onload() {
    await this.loadSettings();
    this.events = new CoreSearchAssistantEvents();
    this.searchInterface = this.addChild(
      new SearchComponentInterface(this.app, this, this.events)
    );
    this.controller = this.addChild(
      new Controller(this.app, this, this.events, this.searchInterface)
    );
    this.watchLayoutChange();
    this.setSvelteStoreValues();
    this.addSettingTab(new CoreSearchAssistantSettingTab(this.app, this));
  }
  // override onunload() {}
  async loadSettings() {
    this.settings = deepMerge(DEFAULT_SETTINGS, await this.loadData());
  }
  async saveSettings() {
    await this.saveData(this.settings);
  }
  renewController() {
    if (this.controller) {
      this.removeChild(this.controller);
    }
    if (this.events === void 0) {
      throw "[ERROR in Core Search Interface] failed to renewController: plugin.events = undefined";
    }
    if (this.searchInterface === void 0) {
      throw "[ERROR in Core Search Interface] failed to renewController: plugin.searchInterface = undefined";
    }
    this.controller = this.addChild(
      new Controller(this.app, this, this.events, this.searchInterface)
    );
  }
  watchLayoutChange() {
    this.app.workspace.onLayoutReady(() => {
      this.app.workspace.on("layout-change", async () => {
        if (await this.controller?.layoutChanged()) {
          this.renewController();
        }
      });
    });
  }
  setSvelteStoreValues() {
    plugin.set(this);
    app.set(this.app);
  }
};

/* nosourcemap */