import { $ as EditorView, At as Facet, Bt as codePointAt, Ct as Annotation, Et as CharCategory, Ft as RangeValue, Gt as fromCodePoint, Ht as combineConfig, I as syntaxTree, It as StateEffect, Lt as StateField, Mt as Prec, Nt as RangeSet, Ot as EditorSelection, Q as Direction, Rt as Text, Vt as codePointSize, Z as Decoration, ht as logException, j as indentUnit, jt as MapMode, nt as WidgetType, pt as keymap, st as getTooltip, tt as ViewPlugin, xt as showTooltip, zt as Transaction } from "./dist-U4F-tbMs.js";
var CompletionContext = class {
  constructor(r8, M, N, P) {
    this.state = r8, this.pos = M, this.explicit = N, this.view = P, this.abortListeners = [], this.abortOnDocChange = false;
  }
  tokenBefore(r8) {
    let M = syntaxTree(this.state).resolveInner(this.pos, -1);
    for (; M && r8.indexOf(M.name) < 0; ) M = M.parent;
    return M ? {
      from: M.from,
      to: this.pos,
      text: this.state.sliceDoc(M.from, this.pos),
      type: M.type
    } : null;
  }
  matchBefore(r8) {
    let M = this.state.doc.lineAt(this.pos), N = Math.max(M.from, this.pos - 250), P = M.text.slice(N - M.from, this.pos - M.from), F = P.search(ensureAnchor(r8, false));
    return F < 0 ? null : {
      from: N + F,
      to: this.pos,
      text: P.slice(F)
    };
  }
  get aborted() {
    return this.abortListeners == null;
  }
  addEventListener(r8, M, N) {
    r8 == "abort" && this.abortListeners && (this.abortListeners.push(M), N && N.onDocChange && (this.abortOnDocChange = true));
  }
};
function toSet(r8) {
  let M = Object.keys(r8).join(""), N = /\w/.test(M);
  return N && (M = M.replace(/\w/g, "")), `[${N ? "\\w" : ""}${M.replace(/[^\w\s]/g, "\\$&")}]`;
}
function prefixMatch(r8) {
  let M = /* @__PURE__ */ Object.create(null), N = /* @__PURE__ */ Object.create(null);
  for (let { label: P2 } of r8) {
    M[P2[0]] = true;
    for (let r9 = 1; r9 < P2.length; r9++) N[P2[r9]] = true;
  }
  let P = toSet(M) + toSet(N) + "*$";
  return [/* @__PURE__ */ RegExp("^" + P), new RegExp(P)];
}
function completeFromList(r8) {
  let M = r8.map((r9) => typeof r9 == "string" ? { label: r9 } : r9), [N, P] = M.every((r9) => /^\w+$/.test(r9.label)) ? [/\w*$/, /\w+$/] : prefixMatch(M);
  return (r9) => {
    let F = r9.matchBefore(P);
    return F || r9.explicit ? {
      from: F ? F.from : r9.pos,
      options: M,
      validFor: N
    } : null;
  };
}
function ifNotIn(r8, M) {
  return (N) => {
    for (let M2 = syntaxTree(N.state).resolveInner(N.pos, -1); M2; M2 = M2.parent) {
      if (r8.indexOf(M2.name) > -1) return null;
      if (M2.type.isTop) break;
    }
    return M(N);
  };
}
var Option = class {
  constructor(r8, M, N, P) {
    this.completion = r8, this.source = M, this.match = N, this.score = P;
  }
};
function cur(r8) {
  return r8.selection.main.from;
}
function ensureAnchor(r8, M) {
  let { source: N } = r8, P = M && N[0] != "^", F = N[N.length - 1] != "$";
  return !P && !F ? r8 : RegExp(`${P ? "^" : ""}(?:${N})${F ? "$" : ""}`, r8.flags ?? (r8.ignoreCase ? "i" : ""));
}
var pickedCompletion = /* @__PURE__ */ Annotation.define();
function insertCompletionText(r8, M, N, P) {
  let { main: F } = r8.selection, I = N - F.from, L = P - F.from;
  return {
    ...r8.changeByRange((R) => {
      if (R != F && N != P && r8.sliceDoc(R.from + I, R.from + L) != r8.sliceDoc(N, P)) return { range: R };
      let z = r8.toText(M);
      return {
        changes: {
          from: R.from + I,
          to: P == F.from ? R.to : R.from + L,
          insert: z
        },
        range: EditorSelection.cursor(R.from + I + z.length)
      };
    }),
    scrollIntoView: true,
    userEvent: "input.complete"
  };
}
var SourceCache = /* @__PURE__ */ new WeakMap();
function asSource(r8) {
  if (!Array.isArray(r8)) return r8;
  let M = SourceCache.get(r8);
  return M || SourceCache.set(r8, M = completeFromList(r8)), M;
}
var startCompletionEffect = /* @__PURE__ */ StateEffect.define(), closeCompletionEffect = /* @__PURE__ */ StateEffect.define(), FuzzyMatcher = class {
  constructor(r8) {
    this.pattern = r8, this.chars = [], this.folded = [], this.any = [], this.precise = [], this.byWord = [], this.score = 0, this.matched = [];
    for (let M = 0; M < r8.length; ) {
      let P = codePointAt(r8, M), F = codePointSize(P);
      this.chars.push(P);
      let I = r8.slice(M, M + F), L = I.toUpperCase();
      this.folded.push(codePointAt(L == I ? I.toLowerCase() : L, 0)), M += F;
    }
    this.astral = r8.length != this.chars.length;
  }
  ret(r8, M) {
    return this.score = r8, this.matched = M, this;
  }
  match(r8) {
    if (this.pattern.length == 0) return this.ret(-100, []);
    if (r8.length < this.pattern.length) return null;
    let { chars: M, folded: P, any: F, precise: I, byWord: R } = this;
    if (M.length == 1) {
      let F2 = codePointAt(r8, 0), I2 = codePointSize(F2), L = I2 == r8.length ? 0 : -100;
      if (F2 != M[0]) if (F2 == P[0]) L += -200;
      else return null;
      return this.ret(L, [0, I2]);
    }
    let z = r8.indexOf(this.pattern);
    if (z == 0) return this.ret(r8.length == this.pattern.length ? 0 : -100, [0, this.pattern.length]);
    let B = M.length, V = 0;
    if (z < 0) {
      for (let I2 = 0, L = Math.min(r8.length, 200); I2 < L && V < B; ) {
        let L2 = codePointAt(r8, I2);
        (L2 == M[V] || L2 == P[V]) && (F[V++] = I2), I2 += codePointSize(L2);
      }
      if (V < B) return null;
    }
    let H = 0, U = 0, W = false, G = 0, K = -1, J = -1, Y = /[a-z]/.test(r8), X = true;
    for (let F2 = 0, V2 = Math.min(r8.length, 200), Z = 0; F2 < V2 && U < B; ) {
      let V3 = codePointAt(r8, F2);
      z < 0 && (H < B && V3 == M[H] && (I[H++] = F2), G < B && (V3 == M[G] || V3 == P[G] ? (G == 0 && (K = F2), J = F2 + 1, G++) : G = 0));
      let Q, $ = V3 < 255 ? V3 >= 48 && V3 <= 57 || V3 >= 97 && V3 <= 122 ? 2 : V3 >= 65 && V3 <= 90 ? 1 : 0 : (Q = fromCodePoint(V3)) == Q.toLowerCase() ? Q == Q.toUpperCase() ? 0 : 2 : 1;
      (!F2 || $ == 1 && Y || Z == 0 && $ != 0) && (M[U] == V3 || P[U] == V3 && (W = true) ? R[U++] = F2 : R.length && (X = false)), Z = $, F2 += codePointSize(V3);
    }
    return U == B && R[0] == 0 && X ? this.result(-100 + (W ? -200 : 0), R, r8) : G == B && K == 0 ? this.ret(-200 - r8.length + (J == r8.length ? 0 : -100), [0, J]) : z > -1 ? this.ret(-700 - r8.length, [z, z + this.pattern.length]) : G == B ? this.ret(-900 - r8.length, [K, J]) : U == B ? this.result(-100 + (W ? -200 : 0) + -700 + (X ? 0 : -1100), R, r8) : M.length == 2 ? null : this.result((F[0] ? -700 : 0) + -200 + -1100, F, r8);
  }
  result(r8, M, P) {
    let F = [], I = 0;
    for (let r9 of M) {
      let M2 = r9 + (this.astral ? codePointSize(codePointAt(P, r9)) : 1);
      I && F[I - 1] == r9 ? F[I - 1] = M2 : (F[I++] = r9, F[I++] = M2);
    }
    return this.ret(r8 - P.length, F);
  }
}, StrictMatcher = class {
  constructor(r8) {
    this.pattern = r8, this.matched = [], this.score = 0, this.folded = r8.toLowerCase();
  }
  match(r8) {
    if (r8.length < this.pattern.length) return null;
    let M = r8.slice(0, this.pattern.length), N = M == this.pattern ? 0 : M.toLowerCase() == this.folded ? -200 : null;
    return N == null ? null : (this.matched = [0, M.length], this.score = N + (r8.length == this.pattern.length ? 0 : -100), this);
  }
}, completionConfig = /* @__PURE__ */ Facet.define({ combine(r8) {
  return combineConfig(r8, {
    activateOnTyping: true,
    activateOnCompletion: () => false,
    activateOnTypingDelay: 100,
    selectOnOpen: true,
    override: null,
    closeOnBlur: true,
    maxRenderedOptions: 100,
    defaultKeymap: true,
    tooltipClass: () => "",
    optionClass: () => "",
    aboveCursor: false,
    icons: true,
    addToOptions: [],
    positionInfo: defaultPositionInfo,
    filterStrict: false,
    compareCompletions: (r9, M) => (r9.sortText || r9.label).localeCompare(M.sortText || M.label),
    interactionDelay: 75,
    updateSyncTime: 100
  }, {
    defaultKeymap: (r9, M) => r9 && M,
    closeOnBlur: (r9, M) => r9 && M,
    icons: (r9, M) => r9 && M,
    tooltipClass: (r9, M) => (N) => joinClass(r9(N), M(N)),
    optionClass: (r9, M) => (N) => joinClass(r9(N), M(N)),
    addToOptions: (r9, M) => r9.concat(M),
    filterStrict: (r9, M) => r9 || M
  });
} });
function joinClass(r8, M) {
  return r8 ? M ? r8 + " " + M : r8 : M;
}
function defaultPositionInfo(r8, M, N, P, F, I) {
  let L = r8.textDirection == Direction.RTL, R = L, z = false, B = "top", V, H, U = M.left - F.left, W = F.right - M.right, K = P.right - P.left, q = P.bottom - P.top;
  if (R && U < Math.min(K, W) ? R = false : !R && W < Math.min(K, U) && (R = true), K <= (R ? U : W)) V = Math.max(F.top, Math.min(N.top, F.bottom - q)) - M.top, H = Math.min(400, R ? U : W);
  else {
    z = true, H = Math.min(400, (L ? M.right : F.right - M.left) - 30);
    let r9 = F.bottom - M.bottom;
    r9 >= q || r9 > M.top ? V = N.bottom - M.top : (B = "bottom", V = M.bottom - N.top);
  }
  let J = (M.bottom - M.top) / I.offsetHeight, Y = (M.right - M.left) / I.offsetWidth;
  return {
    style: `${B}: ${V / J}px; max-width: ${H / Y}px`,
    class: "cm-completionInfo-" + (z ? L ? "left-narrow" : "right-narrow" : R ? "left" : "right")
  };
}
var setSelectedEffect = /* @__PURE__ */ StateEffect.define();
function optionContent(r8) {
  let M = r8.addToOptions.slice();
  return r8.icons && M.push({
    render(r9) {
      let M2 = document.createElement("div");
      return M2.classList.add("cm-completionIcon"), r9.type && M2.classList.add(...r9.type.split(/\s+/g).map((r10) => "cm-completionIcon-" + r10)), M2.setAttribute("aria-hidden", "true"), M2;
    },
    position: 20
  }), M.push({
    render(r9, M2, N, P) {
      let F = document.createElement("span");
      F.className = "cm-completionLabel";
      let I = r9.displayLabel || r9.label, L = 0;
      for (let r10 = 0; r10 < P.length; ) {
        let M3 = P[r10++], N2 = P[r10++];
        M3 > L && F.appendChild(document.createTextNode(I.slice(L, M3)));
        let R = F.appendChild(document.createElement("span"));
        R.appendChild(document.createTextNode(I.slice(M3, N2))), R.className = "cm-completionMatchedText", L = N2;
      }
      return L < I.length && F.appendChild(document.createTextNode(I.slice(L))), F;
    },
    position: 50
  }, {
    render(r9) {
      if (!r9.detail) return null;
      let M2 = document.createElement("span");
      return M2.className = "cm-completionDetail", M2.textContent = r9.detail, M2;
    },
    position: 80
  }), M.sort((r9, M2) => r9.position - M2.position).map((r9) => r9.render);
}
function rangeAroundSelected(r8, M, N) {
  if (r8 <= N) return {
    from: 0,
    to: r8
  };
  if (M < 0 && (M = 0), M <= r8 >> 1) {
    let r9 = Math.floor(M / N);
    return {
      from: r9 * N,
      to: (r9 + 1) * N
    };
  }
  let P = Math.floor((r8 - M) / N);
  return {
    from: r8 - (P + 1) * N,
    to: r8 - P * N
  };
}
var CompletionTooltip = class {
  constructor(r8, M, N) {
    this.view = r8, this.stateField = M, this.applyCompletion = N, this.info = null, this.infoDestroy = null, this.placeInfoReq = {
      read: () => this.measureInfo(),
      write: (r9) => this.placeInfo(r9),
      key: this
    }, this.space = null, this.currentClass = "";
    let P = r8.state.field(M), { options: F, selected: I } = P.open, L = r8.state.facet(completionConfig);
    this.optionContent = optionContent(L), this.optionClass = L.optionClass, this.tooltipClass = L.tooltipClass, this.range = rangeAroundSelected(F.length, I, L.maxRenderedOptions), this.dom = document.createElement("div"), this.dom.className = "cm-tooltip-autocomplete", this.updateTooltipClass(r8.state), this.dom.addEventListener("mousedown", (N2) => {
      let { options: P2 } = r8.state.field(M).open;
      for (let M2 = N2.target, F2; M2 && M2 != this.dom; M2 = M2.parentNode) if (M2.nodeName == "LI" && (F2 = /-(\d+)$/.exec(M2.id)) && +F2[1] < P2.length) {
        this.applyCompletion(r8, P2[+F2[1]]), N2.preventDefault();
        return;
      }
      if (N2.target == this.list) {
        let M2 = this.list.classList.contains("cm-completionListIncompleteTop") && N2.clientY < this.list.firstChild.getBoundingClientRect().top ? this.range.from - 1 : this.list.classList.contains("cm-completionListIncompleteBottom") && N2.clientY > this.list.lastChild.getBoundingClientRect().bottom ? this.range.to : null;
        M2 != null && (r8.dispatch({ effects: setSelectedEffect.of(M2) }), N2.preventDefault());
      }
    }), this.dom.addEventListener("focusout", (M2) => {
      let N2 = r8.state.field(this.stateField, false);
      N2 && N2.tooltip && r8.state.facet(completionConfig).closeOnBlur && M2.relatedTarget != r8.contentDOM && r8.dispatch({ effects: closeCompletionEffect.of(null) });
    }), this.showOptions(F, P.id);
  }
  mount() {
    this.updateSel();
  }
  showOptions(r8, M) {
    this.list && this.list.remove(), this.list = this.dom.appendChild(this.createListBox(r8, M, this.range)), this.list.addEventListener("scroll", () => {
      this.info && this.view.requestMeasure(this.placeInfoReq);
    });
  }
  update(r8) {
    var _a;
    let M = r8.state.field(this.stateField), N = r8.startState.field(this.stateField);
    if (this.updateTooltipClass(r8.state), M != N) {
      let { options: P, selected: F, disabled: I } = M.open;
      (!N.open || N.open.options != P) && (this.range = rangeAroundSelected(P.length, F, r8.state.facet(completionConfig).maxRenderedOptions), this.showOptions(P, M.id)), this.updateSel(), I != ((_a = N.open) == null ? void 0 : _a.disabled) && this.dom.classList.toggle("cm-tooltip-autocomplete-disabled", !!I);
    }
  }
  updateTooltipClass(r8) {
    let M = this.tooltipClass(r8);
    if (M != this.currentClass) {
      for (let r9 of this.currentClass.split(" ")) r9 && this.dom.classList.remove(r9);
      for (let r9 of M.split(" ")) r9 && this.dom.classList.add(r9);
      this.currentClass = M;
    }
  }
  positioned(r8) {
    this.space = r8, this.info && this.view.requestMeasure(this.placeInfoReq);
  }
  updateSel() {
    let r8 = this.view.state.field(this.stateField), M = r8.open;
    (M.selected > -1 && M.selected < this.range.from || M.selected >= this.range.to) && (this.range = rangeAroundSelected(M.options.length, M.selected, this.view.state.facet(completionConfig).maxRenderedOptions), this.showOptions(M.options, r8.id));
    let N = this.updateSelectedOption(M.selected);
    if (N) {
      this.destroyInfo();
      let { completion: P } = M.options[M.selected], { info: F } = P;
      if (!F) return;
      let I = typeof F == "string" ? document.createTextNode(F) : F(P);
      if (!I) return;
      "then" in I ? I.then((M2) => {
        M2 && this.view.state.field(this.stateField, false) == r8 && this.addInfoPane(M2, P);
      }).catch((r9) => logException(this.view.state, r9, "completion info")) : (this.addInfoPane(I, P), N.setAttribute("aria-describedby", this.info.id));
    }
  }
  addInfoPane(r8, M) {
    this.destroyInfo();
    let N = this.info = document.createElement("div");
    if (N.className = "cm-tooltip cm-completionInfo", N.id = "cm-completionInfo-" + Math.floor(Math.random() * 65535).toString(16), r8.nodeType != null) N.appendChild(r8), this.infoDestroy = null;
    else {
      let { dom: M2, destroy: P } = r8;
      N.appendChild(M2), this.infoDestroy = P || null;
    }
    this.dom.appendChild(N), this.view.requestMeasure(this.placeInfoReq);
  }
  updateSelectedOption(r8) {
    let M = null;
    for (let N = this.list.firstChild, P = this.range.from; N; N = N.nextSibling, P++) N.nodeName != "LI" || !N.id ? P-- : P == r8 ? N.hasAttribute("aria-selected") || (N.setAttribute("aria-selected", "true"), M = N) : N.hasAttribute("aria-selected") && (N.removeAttribute("aria-selected"), N.removeAttribute("aria-describedby"));
    return M && scrollIntoView(this.list, M), M;
  }
  measureInfo() {
    let r8 = this.dom.querySelector("[aria-selected]");
    if (!r8 || !this.info) return null;
    let M = this.dom.getBoundingClientRect(), N = this.info.getBoundingClientRect(), P = r8.getBoundingClientRect(), F = this.space;
    if (!F) {
      let r9 = this.dom.ownerDocument.documentElement;
      F = {
        left: 0,
        top: 0,
        right: r9.clientWidth,
        bottom: r9.clientHeight
      };
    }
    return P.top > Math.min(F.bottom, M.bottom) - 10 || P.bottom < Math.max(F.top, M.top) + 10 ? null : this.view.state.facet(completionConfig).positionInfo(this.view, M, P, N, F, this.dom);
  }
  placeInfo(r8) {
    this.info && (r8 ? (r8.style && (this.info.style.cssText = r8.style), this.info.className = "cm-tooltip cm-completionInfo " + (r8.class || "")) : this.info.style.cssText = "top: -1e6px");
  }
  createListBox(r8, M, N) {
    let P = document.createElement("ul");
    P.id = M, P.setAttribute("role", "listbox"), P.setAttribute("aria-expanded", "true"), P.setAttribute("aria-label", this.view.state.phrase("Completions")), P.addEventListener("mousedown", (r9) => {
      r9.target == P && r9.preventDefault();
    });
    let F = null;
    for (let I = N.from; I < N.to; I++) {
      let { completion: L, match: R } = r8[I], { section: z } = L;
      if (z) {
        let r9 = typeof z == "string" ? z : z.name;
        if (r9 != F && (I > N.from || N.from == 0)) if (F = r9, typeof z != "string" && z.header) P.appendChild(z.header(z));
        else {
          let M2 = P.appendChild(document.createElement("completion-section"));
          M2.textContent = r9;
        }
      }
      let B = P.appendChild(document.createElement("li"));
      B.id = M + "-" + I, B.setAttribute("role", "option");
      let V = this.optionClass(L);
      V && (B.className = V);
      for (let r9 of this.optionContent) {
        let M2 = r9(L, this.view.state, this.view, R);
        M2 && B.appendChild(M2);
      }
    }
    return N.from && P.classList.add("cm-completionListIncompleteTop"), N.to < r8.length && P.classList.add("cm-completionListIncompleteBottom"), P;
  }
  destroyInfo() {
    this.info && (this.info = (this.infoDestroy && this.infoDestroy(), this.info.remove(), null));
  }
  destroy() {
    this.destroyInfo();
  }
};
function completionTooltip(r8, M) {
  return (N) => new CompletionTooltip(N, r8, M);
}
function scrollIntoView(r8, M) {
  let N = r8.getBoundingClientRect(), P = M.getBoundingClientRect(), F = N.height / r8.offsetHeight;
  P.top < N.top ? r8.scrollTop -= (N.top - P.top) / F : P.bottom > N.bottom && (r8.scrollTop += (P.bottom - N.bottom) / F);
}
function score(r8) {
  return (r8.boost || 0) * 100 + (r8.apply ? 10 : 0) + (r8.info ? 5 : 0) + (r8.type ? 1 : 0);
}
function sortOptions(r8, M) {
  let N = [], P = null, F = null, I = (r9) => {
    N.push(r9);
    let { section: M2 } = r9.completion;
    if (M2) {
      P || (P = []);
      let r10 = typeof M2 == "string" ? M2 : M2.name;
      P.some((M3) => M3.name == r10) || P.push(typeof M2 == "string" ? { name: r10 } : M2);
    }
  }, L = M.facet(completionConfig);
  for (let P2 of r8) if (P2.hasResult()) {
    let r9 = P2.result.getMatch;
    if (P2.result.filter === false) for (let M2 of P2.result.options) I(new Option(M2, P2.source, r9 ? r9(M2) : [], 1e9 - N.length));
    else {
      let N2 = M.sliceDoc(P2.from, P2.to), R2, z2 = L.filterStrict ? new StrictMatcher(N2) : new FuzzyMatcher(N2);
      for (let M2 of P2.result.options) if (R2 = z2.match(M2.label)) {
        let N3 = M2.displayLabel ? r9 ? r9(M2, R2.matched) : [] : R2.matched, L2 = R2.score + (M2.boost || 0);
        if (I(new Option(M2, P2.source, N3, L2)), typeof M2.section == "object" && M2.section.rank === "dynamic") {
          let { name: r10 } = M2.section;
          F || (F = /* @__PURE__ */ Object.create(null)), F[r10] = Math.max(L2, F[r10] || -1e9);
        }
      }
    }
  }
  if (P) {
    let r9 = /* @__PURE__ */ Object.create(null), M2 = 0, I2 = (r10, M3) => (r10.rank === "dynamic" && M3.rank === "dynamic" ? F[M3.name] - F[r10.name] : 0) || (typeof r10.rank == "number" ? r10.rank : 1e9) - (typeof M3.rank == "number" ? M3.rank : 1e9) || (r10.name < M3.name ? -1 : 1);
    for (let N2 of P.sort(I2)) M2 -= 1e5, r9[N2.name] = M2;
    for (let M3 of N) {
      let { section: N2 } = M3.completion;
      N2 && (M3.score += r9[typeof N2 == "string" ? N2 : N2.name]);
    }
  }
  let R = [], z = null, B = L.compareCompletions;
  for (let r9 of N.sort((r10, M2) => M2.score - r10.score || B(r10.completion, M2.completion))) {
    let M2 = r9.completion;
    !z || z.label != M2.label || z.detail != M2.detail || z.type != null && M2.type != null && z.type != M2.type || z.apply != M2.apply || z.boost != M2.boost ? R.push(r9) : score(r9.completion) > score(z) && (R[R.length - 1] = r9), z = r9.completion;
  }
  return R;
}
var CompletionDialog = class r {
  constructor(r8, M, N, P, F, I) {
    this.options = r8, this.attrs = M, this.tooltip = N, this.timestamp = P, this.selected = F, this.disabled = I;
  }
  setSelected(M, N) {
    return M == this.selected || M >= this.options.length ? this : new r(this.options, makeAttrs(N, M), this.tooltip, this.timestamp, M, this.disabled);
  }
  static build(M, N, P, F, I, L) {
    if (F && !L && M.some((r8) => r8.isPending)) return F.setDisabled();
    let R = sortOptions(M, N);
    if (!R.length) return F && M.some((r8) => r8.isPending) ? F.setDisabled() : null;
    let z = N.facet(completionConfig).selectOnOpen ? 0 : -1;
    if (F && F.selected != z && F.selected != -1) {
      let r8 = F.options[F.selected].completion;
      for (let M2 = 0; M2 < R.length; M2++) if (R[M2].completion == r8) {
        z = M2;
        break;
      }
    }
    return new r(R, makeAttrs(P, z), {
      pos: M.reduce((r8, M2) => M2.hasResult() ? Math.min(r8, M2.from) : r8, 1e8),
      create: createTooltip,
      above: I.aboveCursor
    }, F ? F.timestamp : Date.now(), z, false);
  }
  map(M) {
    return new r(this.options, this.attrs, {
      ...this.tooltip,
      pos: M.mapPos(this.tooltip.pos)
    }, this.timestamp, this.selected, this.disabled);
  }
  setDisabled() {
    return new r(this.options, this.attrs, this.tooltip, this.timestamp, this.selected, true);
  }
}, CompletionState = class r2 {
  constructor(r8, M, N) {
    this.active = r8, this.id = M, this.open = N;
  }
  static start() {
    return new r2(none, "cm-ac-" + Math.floor(Math.random() * 2e6).toString(36), null);
  }
  update(M) {
    let { state: N } = M, P = N.facet(completionConfig), F = (P.override || N.languageDataAt("autocomplete", cur(N)).map(asSource)).map((r8) => (this.active.find((M2) => M2.source == r8) || new ActiveSource(r8, this.active.some((r9) => r9.state != 0) ? 1 : 0)).update(M, P));
    F.length == this.active.length && F.every((r8, M2) => r8 == this.active[M2]) && (F = this.active);
    let I = this.open, L = M.effects.some((r8) => r8.is(setActiveEffect));
    I && M.docChanged && (I = I.map(M.changes)), M.selection || F.some((r8) => r8.hasResult() && M.changes.touchesRange(r8.from, r8.to)) || !sameResults(F, this.active) || L ? I = CompletionDialog.build(F, N, this.id, I, P, L) : I && I.disabled && !F.some((r8) => r8.isPending) && (I = null), !I && F.every((r8) => !r8.isPending) && F.some((r8) => r8.hasResult()) && (F = F.map((r8) => r8.hasResult() ? new ActiveSource(r8.source, 0) : r8));
    for (let r8 of M.effects) r8.is(setSelectedEffect) && (I && (I = I.setSelected(r8.value, this.id)));
    return F == this.active && I == this.open ? this : new r2(F, this.id, I);
  }
  get tooltip() {
    return this.open ? this.open.tooltip : null;
  }
  get attrs() {
    return this.open ? this.open.attrs : this.active.length ? baseAttrs : noAttrs;
  }
};
function sameResults(r8, M) {
  if (r8 == M) return true;
  for (let N = 0, P = 0; ; ) {
    for (; N < r8.length && !r8[N].hasResult(); ) N++;
    for (; P < M.length && !M[P].hasResult(); ) P++;
    let F = N == r8.length, I = P == M.length;
    if (F || I) return F == I;
    if (r8[N++].result != M[P++].result) return false;
  }
}
var baseAttrs = { "aria-autocomplete": "list" }, noAttrs = {};
function makeAttrs(r8, M) {
  let N = {
    "aria-autocomplete": "list",
    "aria-haspopup": "listbox",
    "aria-controls": r8
  };
  return M > -1 && (N["aria-activedescendant"] = r8 + "-" + M), N;
}
var none = [];
function getUpdateType(r8, M) {
  if (r8.isUserEvent("input.complete")) {
    let N2 = r8.annotation(pickedCompletion);
    if (N2 && M.activateOnCompletion(N2)) return 12;
  }
  let N = r8.isUserEvent("input.type");
  return N && M.activateOnTyping ? 5 : N ? 1 : r8.isUserEvent("delete.backward") ? 2 : r8.selection ? 8 : r8.docChanged ? 16 : 0;
}
var ActiveSource = class r3 {
  constructor(r8, M, N = false) {
    this.source = r8, this.state = M, this.explicit = N;
  }
  hasResult() {
    return false;
  }
  get isPending() {
    return this.state == 1;
  }
  update(M, N) {
    let P = getUpdateType(M, N), F = this;
    (P & 8 || P & 16 && this.touches(M)) && (F = new r3(F.source, 0)), P & 4 && F.state == 0 && (F = new r3(this.source, 1)), F = F.updateFor(M, P);
    for (let N2 of M.effects) if (N2.is(startCompletionEffect)) F = new r3(F.source, 1, N2.value);
    else if (N2.is(closeCompletionEffect)) F = new r3(F.source, 0);
    else if (N2.is(setActiveEffect)) for (let r8 of N2.value) r8.source == F.source && (F = r8);
    return F;
  }
  updateFor(r8, M) {
    return this.map(r8.changes);
  }
  map(r8) {
    return this;
  }
  touches(r8) {
    return r8.changes.touchesRange(cur(r8.state));
  }
}, ActiveResult = class r4 extends ActiveSource {
  constructor(r8, M, N, P, F, I) {
    super(r8, 3, M), this.limit = N, this.result = P, this.from = F, this.to = I;
  }
  hasResult() {
    return true;
  }
  updateFor(M, N) {
    if (!(N & 3)) return this.map(M.changes);
    let P = this.result;
    P.map && !M.changes.empty && (P = P.map(P, M.changes));
    let F = M.changes.mapPos(this.from), I = M.changes.mapPos(this.to, 1), L = cur(M.state);
    if (L > I || !P || N & 2 && (cur(M.startState) == this.from || L < this.limit)) return new ActiveSource(this.source, N & 4 ? 1 : 0);
    let R = M.changes.mapPos(this.limit);
    return checkValid(P.validFor, M.state, F, I) ? new r4(this.source, this.explicit, R, P, F, I) : P.update && (P = P.update(P, F, I, new CompletionContext(M.state, L, false))) ? new r4(this.source, this.explicit, R, P, P.from, P.to ?? cur(M.state)) : new ActiveSource(this.source, 1, this.explicit);
  }
  map(M) {
    return M.empty ? this : (this.result.map ? this.result.map(this.result, M) : this.result) ? new r4(this.source, this.explicit, M.mapPos(this.limit), this.result, M.mapPos(this.from), M.mapPos(this.to, 1)) : new ActiveSource(this.source, 0);
  }
  touches(r8) {
    return r8.changes.touchesRange(this.from, this.to);
  }
};
function checkValid(r8, M, N, P) {
  if (!r8) return false;
  let F = M.sliceDoc(N, P);
  return typeof r8 == "function" ? r8(F, N, P, M) : ensureAnchor(r8, true).test(F);
}
var setActiveEffect = /* @__PURE__ */ StateEffect.define({ map(r8, M) {
  return r8.map((r9) => r9.map(M));
} }), completionState = /* @__PURE__ */ StateField.define({
  create() {
    return CompletionState.start();
  },
  update(r8, M) {
    return r8.update(M);
  },
  provide: (M) => [showTooltip.from(M, (r8) => r8.tooltip), EditorView.contentAttributes.from(M, (r8) => r8.attrs)]
});
function applyCompletion(r8, M) {
  let N = M.completion.apply || M.completion.label, P = r8.state.field(completionState).active.find((r9) => r9.source == M.source);
  return P instanceof ActiveResult ? (typeof N == "string" ? r8.dispatch({
    ...insertCompletionText(r8.state, N, P.from, P.to),
    annotations: pickedCompletion.of(M.completion)
  }) : N(r8, M.completion, P.from, P.to), true) : false;
}
var createTooltip = /* @__PURE__ */ completionTooltip(completionState, applyCompletion);
function moveCompletionSelection(r8, M = "option") {
  return (N) => {
    let P = N.state.field(completionState, false);
    if (!P || !P.open || P.open.disabled || Date.now() - P.open.timestamp < N.state.facet(completionConfig).interactionDelay) return false;
    let F = 1, I;
    M == "page" && (I = getTooltip(N, P.open.tooltip)) && (F = Math.max(2, Math.floor(I.dom.offsetHeight / I.dom.querySelector("li").offsetHeight) - 1));
    let { length: L } = P.open.options, R = P.open.selected > -1 ? P.open.selected + F * (r8 ? 1 : -1) : r8 ? 0 : L - 1;
    return R < 0 ? R = M == "page" ? 0 : L - 1 : R >= L && (R = M == "page" ? L - 1 : 0), N.dispatch({ effects: setSelectedEffect.of(R) }), true;
  };
}
var acceptCompletion = (r8) => {
  let M = r8.state.field(completionState, false);
  return r8.state.readOnly || !M || !M.open || M.open.selected < 0 || M.open.disabled || Date.now() - M.open.timestamp < r8.state.facet(completionConfig).interactionDelay ? false : applyCompletion(r8, M.open.options[M.open.selected]);
}, startCompletion = (r8) => r8.state.field(completionState, false) ? (r8.dispatch({ effects: startCompletionEffect.of(true) }), true) : false, closeCompletion = (r8) => {
  let M = r8.state.field(completionState, false);
  return !M || !M.active.some((r9) => r9.state != 0) ? false : (r8.dispatch({ effects: closeCompletionEffect.of(null) }), true);
}, RunningQuery = class {
  constructor(r8, M) {
    this.active = r8, this.context = M, this.time = Date.now(), this.updates = [], this.done = void 0;
  }
}, MaxUpdateCount = 50, MinAbortTime = 1e3, completionPlugin = /* @__PURE__ */ ViewPlugin.fromClass(class {
  constructor(r8) {
    this.view = r8, this.debounceUpdate = -1, this.running = [], this.debounceAccept = -1, this.pendingStart = false, this.composing = 0;
    for (let M of r8.state.field(completionState).active) M.isPending && this.startQuery(M);
  }
  update(r8) {
    let M = r8.state.field(completionState), N = r8.state.facet(completionConfig);
    if (!r8.selectionSet && !r8.docChanged && r8.startState.field(completionState) == M) return;
    let P = r8.transactions.some((r9) => {
      let M2 = getUpdateType(r9, N);
      return M2 & 8 || (r9.selection || r9.docChanged) && !(M2 & 3);
    });
    for (let M2 = 0; M2 < this.running.length; M2++) {
      let N2 = this.running[M2];
      if (P || N2.context.abortOnDocChange && r8.docChanged || N2.updates.length + r8.transactions.length > MaxUpdateCount && Date.now() - N2.time > MinAbortTime) {
        for (let r9 of N2.context.abortListeners) try {
          r9();
        } catch (r10) {
          logException(this.view.state, r10);
        }
        N2.context.abortListeners = null, this.running.splice(M2--, 1);
      } else N2.updates.push(...r8.transactions);
    }
    this.debounceUpdate > -1 && clearTimeout(this.debounceUpdate), r8.transactions.some((r9) => r9.effects.some((r10) => r10.is(startCompletionEffect))) && (this.pendingStart = true);
    let F = this.pendingStart ? 50 : N.activateOnTypingDelay;
    if (this.debounceUpdate = M.active.some((r9) => r9.isPending && !this.running.some((M2) => M2.active.source == r9.source)) ? setTimeout(() => this.startUpdate(), F) : -1, this.composing != 0) for (let M2 of r8.transactions) M2.isUserEvent("input.type") ? this.composing = 2 : this.composing == 2 && M2.selection && (this.composing = 3);
  }
  startUpdate() {
    this.debounceUpdate = -1, this.pendingStart = false;
    let { state: r8 } = this.view, M = r8.field(completionState);
    for (let r9 of M.active) r9.isPending && !this.running.some((M2) => M2.active.source == r9.source) && this.startQuery(r9);
    this.running.length && M.open && M.open.disabled && (this.debounceAccept = setTimeout(() => this.accept(), this.view.state.facet(completionConfig).updateSyncTime));
  }
  startQuery(r8) {
    let { state: M } = this.view, N = new CompletionContext(M, cur(M), r8.explicit, this.view), P = new RunningQuery(r8, N);
    this.running.push(P), Promise.resolve(r8.source(N)).then((r9) => {
      P.context.aborted || (P.done = r9 || null, this.scheduleAccept());
    }, (r9) => {
      this.view.dispatch({ effects: closeCompletionEffect.of(null) }), logException(this.view.state, r9);
    });
  }
  scheduleAccept() {
    this.running.every((r8) => r8.done !== void 0) ? this.accept() : this.debounceAccept < 0 && (this.debounceAccept = setTimeout(() => this.accept(), this.view.state.facet(completionConfig).updateSyncTime));
  }
  accept() {
    this.debounceAccept > -1 && clearTimeout(this.debounceAccept), this.debounceAccept = -1;
    let r8 = [], M = this.view.state.facet(completionConfig), N = this.view.state.field(completionState);
    for (let P = 0; P < this.running.length; P++) {
      let F = this.running[P];
      if (F.done === void 0) continue;
      if (this.running.splice(P--, 1), F.done) {
        let N2 = cur(F.updates.length ? F.updates[0].startState : this.view.state), P2 = Math.min(N2, F.done.from + (F.active.explicit ? 0 : 1)), I2 = new ActiveResult(F.active.source, F.active.explicit, P2, F.done, F.done.from, F.done.to ?? N2);
        for (let r9 of F.updates) I2 = I2.update(r9, M);
        if (I2.hasResult()) {
          r8.push(I2);
          continue;
        }
      }
      let I = N.active.find((r9) => r9.source == F.active.source);
      if (I && I.isPending) if (F.done == null) {
        let N2 = new ActiveSource(F.active.source, 0);
        for (let r9 of F.updates) N2 = N2.update(r9, M);
        N2.isPending || r8.push(N2);
      } else this.startQuery(I);
    }
    (r8.length || N.open && N.open.disabled) && this.view.dispatch({ effects: setActiveEffect.of(r8) });
  }
}, { eventHandlers: {
  blur(r8) {
    let M = this.view.state.field(completionState, false);
    if (M && M.tooltip && this.view.state.facet(completionConfig).closeOnBlur) {
      let N = M.open && getTooltip(this.view, M.open.tooltip);
      (!N || !N.dom.contains(r8.relatedTarget)) && setTimeout(() => this.view.dispatch({ effects: closeCompletionEffect.of(null) }), 10);
    }
  },
  compositionstart() {
    this.composing = 1;
  },
  compositionend() {
    this.composing == 3 && setTimeout(() => this.view.dispatch({ effects: startCompletionEffect.of(false) }), 20), this.composing = 0;
  }
} }), windows = typeof navigator == "object" && /* @__PURE__ */ /Win/.test(navigator.platform), commitCharacters = /* @__PURE__ */ Prec.highest(/* @__PURE__ */ EditorView.domEventHandlers({ keydown(r8, M) {
  let N = M.state.field(completionState, false);
  if (!N || !N.open || N.open.disabled || N.open.selected < 0 || r8.key.length > 1 || r8.ctrlKey && !(windows && r8.altKey) || r8.metaKey) return false;
  let P = N.open.options[N.open.selected], F = N.active.find((r9) => r9.source == P.source), I = P.completion.commitCharacters || F.result.commitCharacters;
  return I && I.indexOf(r8.key) > -1 && applyCompletion(M, P), false;
} })), baseTheme = /* @__PURE__ */ EditorView.baseTheme({
  ".cm-tooltip.cm-tooltip-autocomplete": { "& > ul": {
    fontFamily: "monospace",
    whiteSpace: "nowrap",
    overflow: "hidden auto",
    maxWidth_fallback: "700px",
    maxWidth: "min(700px, 95vw)",
    minWidth: "250px",
    maxHeight: "10em",
    height: "100%",
    listStyle: "none",
    margin: 0,
    padding: 0,
    "& > li, & > completion-section": {
      padding: "1px 3px",
      lineHeight: 1.2
    },
    "& > li": {
      overflowX: "hidden",
      textOverflow: "ellipsis",
      cursor: "pointer"
    },
    "& > completion-section": {
      display: "list-item",
      borderBottom: "1px solid silver",
      paddingLeft: "0.5em",
      opacity: 0.7
    }
  } },
  "&light .cm-tooltip-autocomplete ul li[aria-selected]": {
    background: "#17c",
    color: "white"
  },
  "&light .cm-tooltip-autocomplete-disabled ul li[aria-selected]": { background: "#777" },
  "&dark .cm-tooltip-autocomplete ul li[aria-selected]": {
    background: "#347",
    color: "white"
  },
  "&dark .cm-tooltip-autocomplete-disabled ul li[aria-selected]": { background: "#444" },
  ".cm-completionListIncompleteTop:before, .cm-completionListIncompleteBottom:after": {
    content: '"\xB7\xB7\xB7"',
    opacity: 0.5,
    display: "block",
    textAlign: "center"
  },
  ".cm-tooltip.cm-completionInfo": {
    position: "absolute",
    padding: "3px 9px",
    width: "max-content",
    maxWidth: "400px",
    boxSizing: "border-box",
    whiteSpace: "pre-line"
  },
  ".cm-completionInfo.cm-completionInfo-left": { right: "100%" },
  ".cm-completionInfo.cm-completionInfo-right": { left: "100%" },
  ".cm-completionInfo.cm-completionInfo-left-narrow": { right: "30px" },
  ".cm-completionInfo.cm-completionInfo-right-narrow": { left: "30px" },
  "&light .cm-snippetField": { backgroundColor: "#00000022" },
  "&dark .cm-snippetField": { backgroundColor: "#ffffff22" },
  ".cm-snippetFieldPosition": {
    verticalAlign: "text-top",
    width: 0,
    height: "1.15em",
    display: "inline-block",
    margin: "0 -0.7px -.7em",
    borderLeft: "1.4px dotted #888"
  },
  ".cm-completionMatchedText": { textDecoration: "underline" },
  ".cm-completionDetail": {
    marginLeft: "0.5em",
    fontStyle: "italic"
  },
  ".cm-completionIcon": {
    fontSize: "90%",
    width: ".8em",
    display: "inline-block",
    textAlign: "center",
    paddingRight: ".6em",
    opacity: "0.6",
    boxSizing: "content-box"
  },
  ".cm-completionIcon-function, .cm-completionIcon-method": { "&:after": { content: "'\u0192'" } },
  ".cm-completionIcon-class": { "&:after": { content: "'\u25CB'" } },
  ".cm-completionIcon-interface": { "&:after": { content: "'\u25CC'" } },
  ".cm-completionIcon-variable": { "&:after": { content: "'\u{1D465}'" } },
  ".cm-completionIcon-constant": { "&:after": { content: "'\u{1D436}'" } },
  ".cm-completionIcon-type": { "&:after": { content: "'\u{1D461}'" } },
  ".cm-completionIcon-enum": { "&:after": { content: "'\u222A'" } },
  ".cm-completionIcon-property": { "&:after": { content: "'\u25A1'" } },
  ".cm-completionIcon-keyword": { "&:after": { content: "'\u{1F511}\uFE0E'" } },
  ".cm-completionIcon-namespace": { "&:after": { content: "'\u25A2'" } },
  ".cm-completionIcon-text": { "&:after": {
    content: "'abc'",
    fontSize: "50%",
    verticalAlign: "middle"
  } }
}), FieldPos = class {
  constructor(r8, M, N, P) {
    this.field = r8, this.line = M, this.from = N, this.to = P;
  }
}, FieldRange = class r5 {
  constructor(r8, M, N) {
    this.field = r8, this.from = M, this.to = N;
  }
  map(M) {
    let N = M.mapPos(this.from, -1, MapMode.TrackDel), P = M.mapPos(this.to, 1, MapMode.TrackDel);
    return N == null || P == null ? null : new r5(this.field, N, P);
  }
}, Snippet = class r6 {
  constructor(r8, M) {
    this.lines = r8, this.fieldPositions = M;
  }
  instantiate(r8, M) {
    let N = [], P = [M], F = r8.doc.lineAt(M), I = /^\s*/.exec(F.text)[0];
    for (let F2 of this.lines) {
      if (N.length) {
        let N2 = I, L = /^\t*/.exec(F2)[0].length;
        for (let M2 = 0; M2 < L; M2++) N2 += r8.facet(indentUnit);
        P.push(M + N2.length - L), F2 = N2 + F2.slice(L);
      }
      N.push(F2), M += F2.length + 1;
    }
    return {
      text: N,
      ranges: this.fieldPositions.map((r9) => new FieldRange(r9.field, P[r9.line] + r9.from, P[r9.line] + r9.to))
    };
  }
  static parse(M) {
    let N = [], P = [], F = [], I;
    for (let r8 of M.split(/\r\n?|\n/)) {
      for (; I = /[#$]\{(?:(\d+)(?::([^{}]*))?|((?:\\[{}]|[^{}])*))\}/.exec(r8); ) {
        let M2 = I[1] ? +I[1] : null, L = I[2] || I[3] || "", R = -1, z = L.replace(/\\[{}]/g, (r9) => r9[1]);
        for (let r9 = 0; r9 < N.length; r9++) (M2 == null ? z && N[r9].name == z : N[r9].seq == M2) && (R = r9);
        if (R < 0) {
          let r9 = 0;
          for (; r9 < N.length && (M2 == null || N[r9].seq != null && N[r9].seq < M2); ) r9++;
          N.splice(r9, 0, {
            seq: M2,
            name: z
          }), R = r9;
          for (let r10 of F) r10.field >= R && r10.field++;
        }
        for (let r9 of F) if (r9.line == P.length && r9.from > I.index) {
          let M3 = I[2] ? 3 + (I[1] || "").length : 2;
          r9.from -= M3, r9.to -= M3;
        }
        F.push(new FieldPos(R, P.length, I.index, I.index + z.length)), r8 = r8.slice(0, I.index) + L + r8.slice(I.index + I[0].length);
      }
      r8 = r8.replace(/\\([{}])/g, (r9, M2, N2) => {
        for (let r10 of F) r10.line == P.length && r10.from > N2 && (r10.from--, r10.to--);
        return M2;
      }), P.push(r8);
    }
    return new r6(P, F);
  }
}, fieldMarker = /* @__PURE__ */ Decoration.widget({ widget: /* @__PURE__ */ new class extends WidgetType {
  toDOM() {
    let r8 = document.createElement("span");
    return r8.className = "cm-snippetFieldPosition", r8;
  }
  ignoreEvent() {
    return false;
  }
}() }), fieldRange = /* @__PURE__ */ Decoration.mark({ class: "cm-snippetField" }), ActiveSnippet = class r7 {
  constructor(r8, M) {
    this.ranges = r8, this.active = M, this.deco = Decoration.set(r8.map((r9) => (r9.from == r9.to ? fieldMarker : fieldRange).range(r9.from, r9.to)), true);
  }
  map(M) {
    let N = [];
    for (let r8 of this.ranges) {
      let P = r8.map(M);
      if (!P) return null;
      N.push(P);
    }
    return new r7(N, this.active);
  }
  selectionInsideField(r8) {
    return r8.ranges.every((r9) => this.ranges.some((M) => M.field == this.active && M.from <= r9.from && M.to >= r9.to));
  }
}, setActive = /* @__PURE__ */ StateEffect.define({ map(r8, M) {
  return r8 && r8.map(M);
} }), moveToField = /* @__PURE__ */ StateEffect.define(), snippetState = /* @__PURE__ */ StateField.define({
  create() {
    return null;
  },
  update(r8, M) {
    for (let N of M.effects) {
      if (N.is(setActive)) return N.value;
      if (N.is(moveToField) && r8) return new ActiveSnippet(r8.ranges, N.value);
    }
    return r8 && M.docChanged && (r8 = r8.map(M.changes)), r8 && M.selection && !r8.selectionInsideField(M.selection) && (r8 = null), r8;
  },
  provide: (M) => EditorView.decorations.from(M, (r8) => r8 ? r8.deco : Decoration.none)
});
function fieldSelection(r8, M) {
  return EditorSelection.create(r8.filter((r9) => r9.field == M).map((r9) => EditorSelection.range(r9.from, r9.to)));
}
function snippet(r8) {
  let M = Snippet.parse(r8);
  return (r9, N, P, F) => {
    let { text: I, ranges: L } = M.instantiate(r9.state, P), { main: R } = r9.state.selection, z = {
      changes: {
        from: P,
        to: F == R.from ? R.to : F,
        insert: Text.of(I)
      },
      scrollIntoView: true,
      annotations: N ? [pickedCompletion.of(N), Transaction.userEvent.of("input.complete")] : void 0
    };
    if (L.length && (z.selection = fieldSelection(L, 0)), L.some((r10) => r10.field > 0)) {
      let M2 = new ActiveSnippet(L, 0), N2 = z.effects = [setActive.of(M2)];
      r9.state.field(snippetState, false) === void 0 && N2.push(StateEffect.appendConfig.of([
        snippetState,
        addSnippetKeymap,
        snippetPointerHandler,
        baseTheme
      ]));
    }
    r9.dispatch(r9.state.update(z));
  };
}
function moveField(r8) {
  return ({ state: M, dispatch: N }) => {
    let P = M.field(snippetState, false);
    if (!P || r8 < 0 && P.active == 0) return false;
    let F = P.active + r8, I = r8 > 0 && !P.ranges.some((M2) => M2.field == F + r8);
    return N(M.update({
      selection: fieldSelection(P.ranges, F),
      effects: setActive.of(I ? null : new ActiveSnippet(P.ranges, F)),
      scrollIntoView: true
    })), true;
  };
}
var defaultSnippetKeymap = [{
  key: "Tab",
  run: /* @__PURE__ */ moveField(1),
  shift: /* @__PURE__ */ moveField(-1)
}, {
  key: "Escape",
  run: ({ state: r8, dispatch: M }) => r8.field(snippetState, false) ? (M(r8.update({ effects: setActive.of(null) })), true) : false
}], snippetKeymap = /* @__PURE__ */ Facet.define({ combine(r8) {
  return r8.length ? r8[0] : defaultSnippetKeymap;
} }), addSnippetKeymap = /* @__PURE__ */ Prec.highest(/* @__PURE__ */ keymap.compute([snippetKeymap], (r8) => r8.facet(snippetKeymap)));
function snippetCompletion(r8, M) {
  return {
    ...M,
    apply: snippet(r8)
  };
}
var snippetPointerHandler = /* @__PURE__ */ EditorView.domEventHandlers({ mousedown(r8, M) {
  let N = M.state.field(snippetState, false), P;
  if (!N || (P = M.posAtCoords({
    x: r8.clientX,
    y: r8.clientY
  })) == null) return false;
  let F = N.ranges.find((r9) => r9.from <= P && r9.to >= P);
  return !F || F.field == N.active ? false : (M.dispatch({
    selection: fieldSelection(N.ranges, F.field),
    effects: setActive.of(N.ranges.some((r9) => r9.field > F.field) ? new ActiveSnippet(N.ranges, F.field) : null),
    scrollIntoView: true
  }), true);
} }), defaults = {
  brackets: [
    "(",
    "[",
    "{",
    "'",
    '"'
  ],
  before: ")]}:;>",
  stringPrefixes: []
}, closeBracketEffect = /* @__PURE__ */ StateEffect.define({ map(r8, M) {
  return M.mapPos(r8, -1, MapMode.TrackAfter) ?? void 0;
} }), closedBracket = /* @__PURE__ */ new class extends RangeValue {
}();
closedBracket.startSide = 1, closedBracket.endSide = -1;
var bracketState = /* @__PURE__ */ StateField.define({
  create() {
    return RangeSet.empty;
  },
  update(r8, M) {
    if (r8 = r8.map(M.changes), M.selection) {
      let N = M.state.doc.lineAt(M.selection.main.head);
      r8 = r8.update({ filter: (r9) => r9 >= N.from && r9 <= N.to });
    }
    for (let N of M.effects) N.is(closeBracketEffect) && (r8 = r8.update({ add: [closedBracket.range(N.value, N.value + 1)] }));
    return r8;
  }
});
function closeBrackets() {
  return [inputHandler, bracketState];
}
var definedClosing = "()[]{}<>\xAB\xBB\xBB\xAB\uFF3B\uFF3D\uFF5B\uFF5D";
function closing(r8) {
  for (let M = 0; M < 16; M += 2) if (definedClosing.charCodeAt(M) == r8) return definedClosing.charAt(M + 1);
  return fromCodePoint(r8 < 128 ? r8 : r8 + 1);
}
function config(r8, M) {
  return r8.languageDataAt("closeBrackets", M)[0] || defaults;
}
var android = typeof navigator == "object" && /* @__PURE__ */ /Android\b/.test(navigator.userAgent), inputHandler = /* @__PURE__ */ EditorView.inputHandler.of((r8, M, P, F) => {
  if ((android ? r8.composing : r8.compositionStarted) || r8.state.readOnly) return false;
  let I = r8.state.selection.main;
  if (F.length > 2 || F.length == 2 && codePointSize(codePointAt(F, 0)) == 1 || M != I.from || P != I.to) return false;
  let L = insertBracket(r8.state, F);
  return L ? (r8.dispatch(L), true) : false;
}), closeBracketsKeymap = [{
  key: "Backspace",
  run: ({ state: r8, dispatch: M }) => {
    if (r8.readOnly) return false;
    let P = config(r8, r8.selection.main.head).brackets || defaults.brackets, F = null, I = r8.changeByRange((M2) => {
      if (M2.empty) {
        let F2 = prevChar(r8.doc, M2.head);
        for (let I2 of P) if (I2 == F2 && nextChar(r8.doc, M2.head) == closing(codePointAt(I2, 0))) return {
          changes: {
            from: M2.head - I2.length,
            to: M2.head + I2.length
          },
          range: EditorSelection.cursor(M2.head - I2.length)
        };
      }
      return { range: F = M2 };
    });
    return F || M(r8.update(I, {
      scrollIntoView: true,
      userEvent: "delete.backward"
    })), !F;
  }
}];
function insertBracket(r8, M) {
  let P = config(r8, r8.selection.main.head), F = P.brackets || defaults.brackets;
  for (let I of F) {
    let L = closing(codePointAt(I, 0));
    if (M == I) return L == I ? handleSame(r8, I, F.indexOf(I + I + I) > -1, P) : handleOpen(r8, I, L, P.before || defaults.before);
    if (M == L && closedBracketAt(r8, r8.selection.main.from)) return handleClose(r8, I, L);
  }
  return null;
}
function closedBracketAt(r8, M) {
  let N = false;
  return r8.field(bracketState).between(0, r8.doc.length, (r9) => {
    r9 == M && (N = true);
  }), N;
}
function nextChar(r8, M) {
  let P = r8.sliceString(M, M + 2);
  return P.slice(0, codePointSize(codePointAt(P, 0)));
}
function prevChar(r8, M) {
  let P = r8.sliceString(M - 2, M);
  return codePointSize(codePointAt(P, 0)) == P.length ? P : P.slice(1);
}
function handleOpen(r8, M, N, P) {
  let F = null, I = r8.changeByRange((I2) => {
    if (!I2.empty) return {
      changes: [{
        insert: M,
        from: I2.from
      }, {
        insert: N,
        from: I2.to
      }],
      effects: closeBracketEffect.of(I2.to + M.length),
      range: EditorSelection.range(I2.anchor + M.length, I2.head + M.length)
    };
    let L = nextChar(r8.doc, I2.head);
    return !L || /\s/.test(L) || P.indexOf(L) > -1 ? {
      changes: {
        insert: M + N,
        from: I2.head
      },
      effects: closeBracketEffect.of(I2.head + M.length),
      range: EditorSelection.cursor(I2.head + M.length)
    } : { range: F = I2 };
  });
  return F ? null : r8.update(I, {
    scrollIntoView: true,
    userEvent: "input.type"
  });
}
function handleClose(r8, M, N) {
  let P = null, F = r8.changeByRange((M2) => M2.empty && nextChar(r8.doc, M2.head) == N ? {
    changes: {
      from: M2.head,
      to: M2.head + N.length,
      insert: N
    },
    range: EditorSelection.cursor(M2.head + N.length)
  } : P = { range: M2 });
  return P ? null : r8.update(F, {
    scrollIntoView: true,
    userEvent: "input.type"
  });
}
function handleSame(r8, M, N, P) {
  let I = P.stringPrefixes || defaults.stringPrefixes, L = null, R = r8.changeByRange((P2) => {
    if (!P2.empty) return {
      changes: [{
        insert: M,
        from: P2.from
      }, {
        insert: M,
        from: P2.to
      }],
      effects: closeBracketEffect.of(P2.to + M.length),
      range: EditorSelection.range(P2.anchor + M.length, P2.head + M.length)
    };
    let R2 = P2.head, z = nextChar(r8.doc, R2), B;
    if (z == M) {
      if (nodeStart(r8, R2)) return {
        changes: {
          insert: M + M,
          from: R2
        },
        effects: closeBracketEffect.of(R2 + M.length),
        range: EditorSelection.cursor(R2 + M.length)
      };
      if (closedBracketAt(r8, R2)) {
        let P3 = N && r8.sliceDoc(R2, R2 + M.length * 3) == M + M + M ? M + M + M : M;
        return {
          changes: {
            from: R2,
            to: R2 + P3.length,
            insert: P3
          },
          range: EditorSelection.cursor(R2 + P3.length)
        };
      }
    } else if (N && r8.sliceDoc(R2 - 2 * M.length, R2) == M + M && (B = canStartStringAt(r8, R2 - 2 * M.length, I)) > -1 && nodeStart(r8, B)) return {
      changes: {
        insert: M + M + M + M,
        from: R2
      },
      effects: closeBracketEffect.of(R2 + M.length),
      range: EditorSelection.cursor(R2 + M.length)
    };
    else if (r8.charCategorizer(R2)(z) != CharCategory.Word && canStartStringAt(r8, R2, I) > -1 && !probablyInString(r8, R2, M, I)) return {
      changes: {
        insert: M + M,
        from: R2
      },
      effects: closeBracketEffect.of(R2 + M.length),
      range: EditorSelection.cursor(R2 + M.length)
    };
    return { range: L = P2 };
  });
  return L ? null : r8.update(R, {
    scrollIntoView: true,
    userEvent: "input.type"
  });
}
function nodeStart(r8, M) {
  let N = syntaxTree(r8).resolveInner(M + 1);
  return N.parent && N.from == M;
}
function probablyInString(r8, M, N, P) {
  let F = syntaxTree(r8).resolveInner(M, -1), I = P.reduce((r9, M2) => Math.max(r9, M2.length), 0);
  for (let L = 0; L < 5; L++) {
    let L2 = r8.sliceDoc(F.from, Math.min(F.to, F.from + N.length + I)), R = L2.indexOf(N);
    if (!R || R > -1 && P.indexOf(L2.slice(0, R)) > -1) {
      let M2 = F.firstChild;
      for (; M2 && M2.from == F.from && M2.to - M2.from > N.length + R; ) {
        if (r8.sliceDoc(M2.to - N.length, M2.to) == N) return false;
        M2 = M2.firstChild;
      }
      return true;
    }
    let z = F.to == M && F.parent;
    if (!z) break;
    F = z;
  }
  return false;
}
function canStartStringAt(r8, M, N) {
  let P = r8.charCategorizer(M);
  if (P(r8.sliceDoc(M - 1, M)) != CharCategory.Word) return M;
  for (let I of N) {
    let N2 = M - I.length;
    if (r8.sliceDoc(N2, M) == I && P(r8.sliceDoc(N2 - 1, N2)) != CharCategory.Word) return N2;
  }
  return -1;
}
function autocompletion(r8 = {}) {
  return [
    commitCharacters,
    completionState,
    completionConfig.of(r8),
    completionPlugin,
    completionKeymapExt,
    baseTheme
  ];
}
var completionKeymap = [
  {
    key: "Ctrl-Space",
    run: startCompletion
  },
  {
    mac: "Alt-`",
    run: startCompletion
  },
  {
    mac: "Alt-i",
    run: startCompletion
  },
  {
    key: "Escape",
    run: closeCompletion
  },
  {
    key: "ArrowDown",
    run: /* @__PURE__ */ moveCompletionSelection(true)
  },
  {
    key: "ArrowUp",
    run: /* @__PURE__ */ moveCompletionSelection(false)
  },
  {
    key: "PageDown",
    run: /* @__PURE__ */ moveCompletionSelection(true, "page")
  },
  {
    key: "PageUp",
    run: /* @__PURE__ */ moveCompletionSelection(false, "page")
  },
  {
    key: "Enter",
    run: acceptCompletion
  }
], completionKeymapExt = /* @__PURE__ */ Prec.highest(/* @__PURE__ */ keymap.computeN([completionConfig], (r8) => r8.facet(completionConfig).defaultKeymap ? [completionKeymap] : []));
export {
  closeBracketsKeymap as a,
  completionKeymap as c,
  snippet as d,
  snippetCompletion as f,
  closeBrackets as i,
  ifNotIn as l,
  acceptCompletion as n,
  closeCompletion as o,
  autocompletion as r,
  completeFromList as s,
  CompletionContext as t,
  insertCompletionText as u
};
