import { $ as ViewPlugin, At as Prec, Bt as combineConfig, Et as EditorSelection, Ft as StateField, I as syntaxTree, It as Text, Lt as Transaction, Nt as RangeValue, Ot as Facet, Pt as StateEffect, Rt as codePointAt, Ut as fromCodePoint, X as Direction, Y as Decoration, Z as EditorView, at as getTooltip, dt as keymap, et as WidgetType, j as indentUnit, jt as RangeSet, kt as MapMode, pt as logException, wt as CharCategory, xt as Annotation, yt as showTooltip, zt as codePointSize } from "./dist-CCADb07R.js";
var CompletionContext = class {
  constructor(i8, N, P, F) {
    this.state = i8, this.pos = N, this.explicit = P, this.view = F, this.abortListeners = [], this.abortOnDocChange = false;
  }
  tokenBefore(i8) {
    let N = syntaxTree(this.state).resolveInner(this.pos, -1);
    for (; N && i8.indexOf(N.name) < 0; ) N = N.parent;
    return N ? {
      from: N.from,
      to: this.pos,
      text: this.state.sliceDoc(N.from, this.pos),
      type: N.type
    } : null;
  }
  matchBefore(i8) {
    let N = this.state.doc.lineAt(this.pos), P = Math.max(N.from, this.pos - 250), F = N.text.slice(P - N.from, this.pos - N.from), I = F.search(ensureAnchor(i8, false));
    return I < 0 ? null : {
      from: P + I,
      to: this.pos,
      text: F.slice(I)
    };
  }
  get aborted() {
    return this.abortListeners == null;
  }
  addEventListener(i8, N, P) {
    i8 == "abort" && this.abortListeners && (this.abortListeners.push(N), P && P.onDocChange && (this.abortOnDocChange = true));
  }
};
function toSet(i8) {
  let N = Object.keys(i8).join(""), P = /\w/.test(N);
  return P && (N = N.replace(/\w/g, "")), `[${P ? "\\w" : ""}${N.replace(/[^\w\s]/g, "\\$&")}]`;
}
function prefixMatch(i8) {
  let N = /* @__PURE__ */ Object.create(null), P = /* @__PURE__ */ Object.create(null);
  for (let { label: F2 } of i8) {
    N[F2[0]] = true;
    for (let i9 = 1; i9 < F2.length; i9++) P[F2[i9]] = true;
  }
  let F = toSet(N) + toSet(P) + "*$";
  return [/* @__PURE__ */ RegExp("^" + F), new RegExp(F)];
}
function completeFromList(i8) {
  let N = i8.map((i9) => typeof i9 == "string" ? { label: i9 } : i9), [P, F] = N.every((i9) => /^\w+$/.test(i9.label)) ? [/\w*$/, /\w+$/] : prefixMatch(N);
  return (i9) => {
    let I = i9.matchBefore(F);
    return I || i9.explicit ? {
      from: I ? I.from : i9.pos,
      options: N,
      validFor: P
    } : null;
  };
}
function ifNotIn(i8, N) {
  return (P) => {
    for (let N2 = syntaxTree(P.state).resolveInner(P.pos, -1); N2; N2 = N2.parent) {
      if (i8.indexOf(N2.name) > -1) return null;
      if (N2.type.isTop) break;
    }
    return N(P);
  };
}
var Option = class {
  constructor(i8, N, P, F) {
    this.completion = i8, this.source = N, this.match = P, this.score = F;
  }
};
function cur(i8) {
  return i8.selection.main.from;
}
function ensureAnchor(i8, N) {
  let { source: P } = i8, F = N && P[0] != "^", I = P[P.length - 1] != "$";
  return !F && !I ? i8 : RegExp(`${F ? "^" : ""}(?:${P})${I ? "$" : ""}`, i8.flags ?? (i8.ignoreCase ? "i" : ""));
}
var pickedCompletion = /* @__PURE__ */ Annotation.define();
function insertCompletionText(i8, N, P, I) {
  let { main: L } = i8.selection, R = P - L.from, z = I - L.from;
  return {
    ...i8.changeByRange((B) => {
      if (B != L && P != I && i8.sliceDoc(B.from + R, B.from + z) != i8.sliceDoc(P, I)) return { range: B };
      let V = i8.toText(N);
      return {
        changes: {
          from: B.from + R,
          to: I == L.from ? B.to : B.from + z,
          insert: V
        },
        range: EditorSelection.cursor(B.from + R + V.length)
      };
    }),
    scrollIntoView: true,
    userEvent: "input.complete"
  };
}
var SourceCache = /* @__PURE__ */ new WeakMap();
function asSource(i8) {
  if (!Array.isArray(i8)) return i8;
  let N = SourceCache.get(i8);
  return N || SourceCache.set(i8, N = completeFromList(i8)), N;
}
var startCompletionEffect = /* @__PURE__ */ StateEffect.define(), closeCompletionEffect = /* @__PURE__ */ StateEffect.define(), FuzzyMatcher = class {
  constructor(i8) {
    this.pattern = i8, this.chars = [], this.folded = [], this.any = [], this.precise = [], this.byWord = [], this.score = 0, this.matched = [];
    for (let N = 0; N < i8.length; ) {
      let P = codePointAt(i8, N), F = codePointSize(P);
      this.chars.push(P);
      let I = i8.slice(N, N + F), L = I.toUpperCase();
      this.folded.push(codePointAt(L == I ? I.toLowerCase() : L, 0)), N += F;
    }
    this.astral = i8.length != this.chars.length;
  }
  ret(i8, N) {
    return this.score = i8, this.matched = N, this;
  }
  match(i8) {
    if (this.pattern.length == 0) return this.ret(-100, []);
    if (i8.length < this.pattern.length) return null;
    let { chars: N, folded: P, any: F, precise: I, byWord: L } = this;
    if (N.length == 1) {
      let F2 = codePointAt(i8, 0), I2 = codePointSize(F2), L2 = I2 == i8.length ? 0 : -100;
      if (F2 != N[0]) if (F2 == P[0]) L2 += -200;
      else return null;
      return this.ret(L2, [0, I2]);
    }
    let R = i8.indexOf(this.pattern);
    if (R == 0) return this.ret(i8.length == this.pattern.length ? 0 : -100, [0, this.pattern.length]);
    let z = N.length, B = 0;
    if (R < 0) {
      for (let I2 = 0, L2 = Math.min(i8.length, 200); I2 < L2 && B < z; ) {
        let L3 = codePointAt(i8, I2);
        (L3 == N[B] || L3 == P[B]) && (F[B++] = I2), I2 += codePointSize(L3);
      }
      if (B < z) return null;
    }
    let V = 0, H = 0, G = false, K = 0, q = -1, J = -1, Y = /[a-z]/.test(i8), X = true;
    for (let F2 = 0, B2 = Math.min(i8.length, 200), Z = 0; F2 < B2 && H < z; ) {
      let B3 = codePointAt(i8, F2);
      R < 0 && (V < z && B3 == N[V] && (I[V++] = F2), K < z && (B3 == N[K] || B3 == P[K] ? (K == 0 && (q = F2), J = F2 + 1, K++) : K = 0));
      let Q, $ = B3 < 255 ? B3 >= 48 && B3 <= 57 || B3 >= 97 && B3 <= 122 ? 2 : B3 >= 65 && B3 <= 90 ? 1 : 0 : (Q = fromCodePoint(B3)) == Q.toLowerCase() ? Q == Q.toUpperCase() ? 0 : 2 : 1;
      (!F2 || $ == 1 && Y || Z == 0 && $ != 0) && (N[H] == B3 || P[H] == B3 && (G = true) ? L[H++] = F2 : L.length && (X = false)), Z = $, F2 += codePointSize(B3);
    }
    return H == z && L[0] == 0 && X ? this.result(-100 + (G ? -200 : 0), L, i8) : K == z && q == 0 ? this.ret(-200 - i8.length + (J == i8.length ? 0 : -100), [0, J]) : R > -1 ? this.ret(-700 - i8.length, [R, R + this.pattern.length]) : K == z ? this.ret(-900 - i8.length, [q, J]) : H == z ? this.result(-100 + (G ? -200 : 0) + -700 + (X ? 0 : -1100), L, i8) : N.length == 2 ? null : this.result((F[0] ? -700 : 0) + -200 + -1100, F, i8);
  }
  result(i8, N, P) {
    let F = [], I = 0;
    for (let i9 of N) {
      let N2 = i9 + (this.astral ? codePointSize(codePointAt(P, i9)) : 1);
      I && F[I - 1] == i9 ? F[I - 1] = N2 : (F[I++] = i9, F[I++] = N2);
    }
    return this.ret(i8 - P.length, F);
  }
}, StrictMatcher = class {
  constructor(i8) {
    this.pattern = i8, this.matched = [], this.score = 0, this.folded = i8.toLowerCase();
  }
  match(i8) {
    if (i8.length < this.pattern.length) return null;
    let N = i8.slice(0, this.pattern.length), P = N == this.pattern ? 0 : N.toLowerCase() == this.folded ? -200 : null;
    return P == null ? null : (this.matched = [0, N.length], this.score = P + (i8.length == this.pattern.length ? 0 : -100), this);
  }
}, completionConfig = /* @__PURE__ */ Facet.define({ combine(i8) {
  return combineConfig(i8, {
    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: (i9, N) => (i9.sortText || i9.label).localeCompare(N.sortText || N.label),
    interactionDelay: 75,
    updateSyncTime: 100
  }, {
    defaultKeymap: (i9, N) => i9 && N,
    closeOnBlur: (i9, N) => i9 && N,
    icons: (i9, N) => i9 && N,
    tooltipClass: (i9, N) => (P) => joinClass(i9(P), N(P)),
    optionClass: (i9, N) => (P) => joinClass(i9(P), N(P)),
    addToOptions: (i9, N) => i9.concat(N),
    filterStrict: (i9, N) => i9 || N
  });
} });
function joinClass(i8, N) {
  return i8 ? N ? i8 + " " + N : i8 : N;
}
function defaultPositionInfo(i8, N, P, F, I, L) {
  let R = i8.textDirection == Direction.RTL, z = R, B = false, V = "top", H, U, W = N.left - I.left, K = I.right - N.right, q = F.right - F.left, J = F.bottom - F.top;
  if (z && W < Math.min(q, K) ? z = false : !z && K < Math.min(q, W) && (z = true), q <= (z ? W : K)) H = Math.max(I.top, Math.min(P.top, I.bottom - J)) - N.top, U = Math.min(400, z ? W : K);
  else {
    B = true, U = Math.min(400, (R ? N.right : I.right - N.left) - 30);
    let i9 = I.bottom - N.bottom;
    i9 >= J || i9 > N.top ? H = P.bottom - N.top : (V = "bottom", H = N.bottom - P.top);
  }
  let Y = (N.bottom - N.top) / L.offsetHeight, X = (N.right - N.left) / L.offsetWidth;
  return {
    style: `${V}: ${H / Y}px; max-width: ${U / X}px`,
    class: "cm-completionInfo-" + (B ? R ? "left-narrow" : "right-narrow" : z ? "left" : "right")
  };
}
var setSelectedEffect = /* @__PURE__ */ StateEffect.define();
function optionContent(i8) {
  let N = i8.addToOptions.slice();
  return i8.icons && N.push({
    render(i9) {
      let N2 = document.createElement("div");
      return N2.classList.add("cm-completionIcon"), i9.type && N2.classList.add(...i9.type.split(/\s+/g).map((i10) => "cm-completionIcon-" + i10)), N2.setAttribute("aria-hidden", "true"), N2;
    },
    position: 20
  }), N.push({
    render(i9, N2, P, F) {
      let I = document.createElement("span");
      I.className = "cm-completionLabel";
      let L = i9.displayLabel || i9.label, R = 0;
      for (let i10 = 0; i10 < F.length; ) {
        let N3 = F[i10++], P2 = F[i10++];
        N3 > R && I.appendChild(document.createTextNode(L.slice(R, N3)));
        let z = I.appendChild(document.createElement("span"));
        z.appendChild(document.createTextNode(L.slice(N3, P2))), z.className = "cm-completionMatchedText", R = P2;
      }
      return R < L.length && I.appendChild(document.createTextNode(L.slice(R))), I;
    },
    position: 50
  }, {
    render(i9) {
      if (!i9.detail) return null;
      let N2 = document.createElement("span");
      return N2.className = "cm-completionDetail", N2.textContent = i9.detail, N2;
    },
    position: 80
  }), N.sort((i9, N2) => i9.position - N2.position).map((i9) => i9.render);
}
function rangeAroundSelected(i8, N, P) {
  if (i8 <= P) return {
    from: 0,
    to: i8
  };
  if (N < 0 && (N = 0), N <= i8 >> 1) {
    let i9 = Math.floor(N / P);
    return {
      from: i9 * P,
      to: (i9 + 1) * P
    };
  }
  let F = Math.floor((i8 - N) / P);
  return {
    from: i8 - (F + 1) * P,
    to: i8 - F * P
  };
}
var CompletionTooltip = class {
  constructor(i8, N, P) {
    this.view = i8, this.stateField = N, this.applyCompletion = P, this.info = null, this.infoDestroy = null, this.placeInfoReq = {
      read: () => this.measureInfo(),
      write: (i9) => this.placeInfo(i9),
      key: this
    }, this.space = null, this.currentClass = "";
    let F = i8.state.field(N), { options: I, selected: L } = F.open, R = i8.state.facet(completionConfig);
    this.optionContent = optionContent(R), this.optionClass = R.optionClass, this.tooltipClass = R.tooltipClass, this.range = rangeAroundSelected(I.length, L, R.maxRenderedOptions), this.dom = document.createElement("div"), this.dom.className = "cm-tooltip-autocomplete", this.updateTooltipClass(i8.state), this.dom.addEventListener("mousedown", (P2) => {
      let { options: F2 } = i8.state.field(N).open;
      for (let N2 = P2.target, I2; N2 && N2 != this.dom; N2 = N2.parentNode) if (N2.nodeName == "LI" && (I2 = /-(\d+)$/.exec(N2.id)) && +I2[1] < F2.length) {
        this.applyCompletion(i8, F2[+I2[1]]), P2.preventDefault();
        return;
      }
      if (P2.target == this.list) {
        let N2 = this.list.classList.contains("cm-completionListIncompleteTop") && P2.clientY < this.list.firstChild.getBoundingClientRect().top ? this.range.from - 1 : this.list.classList.contains("cm-completionListIncompleteBottom") && P2.clientY > this.list.lastChild.getBoundingClientRect().bottom ? this.range.to : null;
        N2 != null && (i8.dispatch({ effects: setSelectedEffect.of(N2) }), P2.preventDefault());
      }
    }), this.dom.addEventListener("focusout", (N2) => {
      let P2 = i8.state.field(this.stateField, false);
      P2 && P2.tooltip && i8.state.facet(completionConfig).closeOnBlur && N2.relatedTarget != i8.contentDOM && i8.dispatch({ effects: closeCompletionEffect.of(null) });
    }), this.showOptions(I, F.id);
  }
  mount() {
    this.updateSel();
  }
  showOptions(i8, N) {
    this.list && this.list.remove(), this.list = this.dom.appendChild(this.createListBox(i8, N, this.range)), this.list.addEventListener("scroll", () => {
      this.info && this.view.requestMeasure(this.placeInfoReq);
    });
  }
  update(i8) {
    var _a;
    let N = i8.state.field(this.stateField), P = i8.startState.field(this.stateField);
    if (this.updateTooltipClass(i8.state), N != P) {
      let { options: F, selected: I, disabled: L } = N.open;
      (!P.open || P.open.options != F) && (this.range = rangeAroundSelected(F.length, I, i8.state.facet(completionConfig).maxRenderedOptions), this.showOptions(F, N.id)), this.updateSel(), L != ((_a = P.open) == null ? void 0 : _a.disabled) && this.dom.classList.toggle("cm-tooltip-autocomplete-disabled", !!L);
    }
  }
  updateTooltipClass(i8) {
    let N = this.tooltipClass(i8);
    if (N != this.currentClass) {
      for (let i9 of this.currentClass.split(" ")) i9 && this.dom.classList.remove(i9);
      for (let i9 of N.split(" ")) i9 && this.dom.classList.add(i9);
      this.currentClass = N;
    }
  }
  positioned(i8) {
    this.space = i8, this.info && this.view.requestMeasure(this.placeInfoReq);
  }
  updateSel() {
    let i8 = this.view.state.field(this.stateField), N = i8.open;
    (N.selected > -1 && N.selected < this.range.from || N.selected >= this.range.to) && (this.range = rangeAroundSelected(N.options.length, N.selected, this.view.state.facet(completionConfig).maxRenderedOptions), this.showOptions(N.options, i8.id));
    let P = this.updateSelectedOption(N.selected);
    if (P) {
      this.destroyInfo();
      let { completion: F } = N.options[N.selected], { info: I } = F;
      if (!I) return;
      let L = typeof I == "string" ? document.createTextNode(I) : I(F);
      if (!L) return;
      "then" in L ? L.then((N2) => {
        N2 && this.view.state.field(this.stateField, false) == i8 && this.addInfoPane(N2, F);
      }).catch((i9) => logException(this.view.state, i9, "completion info")) : (this.addInfoPane(L, F), P.setAttribute("aria-describedby", this.info.id));
    }
  }
  addInfoPane(i8, N) {
    this.destroyInfo();
    let P = this.info = document.createElement("div");
    if (P.className = "cm-tooltip cm-completionInfo", P.id = "cm-completionInfo-" + Math.floor(Math.random() * 65535).toString(16), i8.nodeType != null) P.appendChild(i8), this.infoDestroy = null;
    else {
      let { dom: N2, destroy: F } = i8;
      P.appendChild(N2), this.infoDestroy = F || null;
    }
    this.dom.appendChild(P), this.view.requestMeasure(this.placeInfoReq);
  }
  updateSelectedOption(i8) {
    let N = null;
    for (let P = this.list.firstChild, F = this.range.from; P; P = P.nextSibling, F++) P.nodeName != "LI" || !P.id ? F-- : F == i8 ? P.hasAttribute("aria-selected") || (P.setAttribute("aria-selected", "true"), N = P) : P.hasAttribute("aria-selected") && (P.removeAttribute("aria-selected"), P.removeAttribute("aria-describedby"));
    return N && scrollIntoView(this.list, N), N;
  }
  measureInfo() {
    let i8 = this.dom.querySelector("[aria-selected]");
    if (!i8 || !this.info) return null;
    let N = this.dom.getBoundingClientRect(), P = this.info.getBoundingClientRect(), F = i8.getBoundingClientRect(), I = this.space;
    if (!I) {
      let i9 = this.dom.ownerDocument.documentElement;
      I = {
        left: 0,
        top: 0,
        right: i9.clientWidth,
        bottom: i9.clientHeight
      };
    }
    return F.top > Math.min(I.bottom, N.bottom) - 10 || F.bottom < Math.max(I.top, N.top) + 10 ? null : this.view.state.facet(completionConfig).positionInfo(this.view, N, F, P, I, this.dom);
  }
  placeInfo(i8) {
    this.info && (i8 ? (i8.style && (this.info.style.cssText = i8.style), this.info.className = "cm-tooltip cm-completionInfo " + (i8.class || "")) : this.info.style.cssText = "top: -1e6px");
  }
  createListBox(i8, N, P) {
    let F = document.createElement("ul");
    F.id = N, F.setAttribute("role", "listbox"), F.setAttribute("aria-expanded", "true"), F.setAttribute("aria-label", this.view.state.phrase("Completions")), F.addEventListener("mousedown", (i9) => {
      i9.target == F && i9.preventDefault();
    });
    let I = null;
    for (let L = P.from; L < P.to; L++) {
      let { completion: R, match: z } = i8[L], { section: B } = R;
      if (B) {
        let i9 = typeof B == "string" ? B : B.name;
        if (i9 != I && (L > P.from || P.from == 0)) if (I = i9, typeof B != "string" && B.header) F.appendChild(B.header(B));
        else {
          let N2 = F.appendChild(document.createElement("completion-section"));
          N2.textContent = i9;
        }
      }
      let V = F.appendChild(document.createElement("li"));
      V.id = N + "-" + L, V.setAttribute("role", "option");
      let H = this.optionClass(R);
      H && (V.className = H);
      for (let i9 of this.optionContent) {
        let N2 = i9(R, this.view.state, this.view, z);
        N2 && V.appendChild(N2);
      }
    }
    return P.from && F.classList.add("cm-completionListIncompleteTop"), P.to < i8.length && F.classList.add("cm-completionListIncompleteBottom"), F;
  }
  destroyInfo() {
    this.info && (this.info = (this.infoDestroy && this.infoDestroy(), this.info.remove(), null));
  }
  destroy() {
    this.destroyInfo();
  }
};
function completionTooltip(i8, N) {
  return (P) => new CompletionTooltip(P, i8, N);
}
function scrollIntoView(i8, N) {
  let P = i8.getBoundingClientRect(), F = N.getBoundingClientRect(), I = P.height / i8.offsetHeight;
  F.top < P.top ? i8.scrollTop -= (P.top - F.top) / I : F.bottom > P.bottom && (i8.scrollTop += (F.bottom - P.bottom) / I);
}
function score(i8) {
  return (i8.boost || 0) * 100 + (i8.apply ? 10 : 0) + (i8.info ? 5 : 0) + (i8.type ? 1 : 0);
}
function sortOptions(i8, N) {
  let P = [], F = null, I = null, L = (i9) => {
    P.push(i9);
    let { section: N2 } = i9.completion;
    if (N2) {
      F || (F = []);
      let i10 = typeof N2 == "string" ? N2 : N2.name;
      F.some((N3) => N3.name == i10) || F.push(typeof N2 == "string" ? { name: i10 } : N2);
    }
  }, R = N.facet(completionConfig);
  for (let F2 of i8) if (F2.hasResult()) {
    let i9 = F2.result.getMatch;
    if (F2.result.filter === false) for (let N2 of F2.result.options) L(new Option(N2, F2.source, i9 ? i9(N2) : [], 1e9 - P.length));
    else {
      let P2 = N.sliceDoc(F2.from, F2.to), z2, B2 = R.filterStrict ? new StrictMatcher(P2) : new FuzzyMatcher(P2);
      for (let N2 of F2.result.options) if (z2 = B2.match(N2.label)) {
        let P3 = N2.displayLabel ? i9 ? i9(N2, z2.matched) : [] : z2.matched, R2 = z2.score + (N2.boost || 0);
        if (L(new Option(N2, F2.source, P3, R2)), typeof N2.section == "object" && N2.section.rank === "dynamic") {
          let { name: i10 } = N2.section;
          I || (I = /* @__PURE__ */ Object.create(null)), I[i10] = Math.max(R2, I[i10] || -1e9);
        }
      }
    }
  }
  if (F) {
    let i9 = /* @__PURE__ */ Object.create(null), N2 = 0, L2 = (i10, N3) => (i10.rank === "dynamic" && N3.rank === "dynamic" ? I[N3.name] - I[i10.name] : 0) || (typeof i10.rank == "number" ? i10.rank : 1e9) - (typeof N3.rank == "number" ? N3.rank : 1e9) || (i10.name < N3.name ? -1 : 1);
    for (let P2 of F.sort(L2)) N2 -= 1e5, i9[P2.name] = N2;
    for (let N3 of P) {
      let { section: P2 } = N3.completion;
      P2 && (N3.score += i9[typeof P2 == "string" ? P2 : P2.name]);
    }
  }
  let z = [], B = null, V = R.compareCompletions;
  for (let i9 of P.sort((i10, N2) => N2.score - i10.score || V(i10.completion, N2.completion))) {
    let N2 = i9.completion;
    !B || B.label != N2.label || B.detail != N2.detail || B.type != null && N2.type != null && B.type != N2.type || B.apply != N2.apply || B.boost != N2.boost ? z.push(i9) : score(i9.completion) > score(B) && (z[z.length - 1] = i9), B = i9.completion;
  }
  return z;
}
var CompletionDialog = class i {
  constructor(i8, N, P, F, I, L) {
    this.options = i8, this.attrs = N, this.tooltip = P, this.timestamp = F, this.selected = I, this.disabled = L;
  }
  setSelected(N, P) {
    return N == this.selected || N >= this.options.length ? this : new i(this.options, makeAttrs(P, N), this.tooltip, this.timestamp, N, this.disabled);
  }
  static build(N, P, F, I, L, R) {
    if (I && !R && N.some((i8) => i8.isPending)) return I.setDisabled();
    let z = sortOptions(N, P);
    if (!z.length) return I && N.some((i8) => i8.isPending) ? I.setDisabled() : null;
    let B = P.facet(completionConfig).selectOnOpen ? 0 : -1;
    if (I && I.selected != B && I.selected != -1) {
      let i8 = I.options[I.selected].completion;
      for (let N2 = 0; N2 < z.length; N2++) if (z[N2].completion == i8) {
        B = N2;
        break;
      }
    }
    return new i(z, makeAttrs(F, B), {
      pos: N.reduce((i8, N2) => N2.hasResult() ? Math.min(i8, N2.from) : i8, 1e8),
      create: createTooltip,
      above: L.aboveCursor
    }, I ? I.timestamp : Date.now(), B, false);
  }
  map(N) {
    return new i(this.options, this.attrs, {
      ...this.tooltip,
      pos: N.mapPos(this.tooltip.pos)
    }, this.timestamp, this.selected, this.disabled);
  }
  setDisabled() {
    return new i(this.options, this.attrs, this.tooltip, this.timestamp, this.selected, true);
  }
}, CompletionState = class i2 {
  constructor(i8, N, P) {
    this.active = i8, this.id = N, this.open = P;
  }
  static start() {
    return new i2(none, "cm-ac-" + Math.floor(Math.random() * 2e6).toString(36), null);
  }
  update(N) {
    let { state: P } = N, F = P.facet(completionConfig), I = (F.override || P.languageDataAt("autocomplete", cur(P)).map(asSource)).map((i8) => (this.active.find((N2) => N2.source == i8) || new ActiveSource(i8, this.active.some((i9) => i9.state != 0) ? 1 : 0)).update(N, F));
    I.length == this.active.length && I.every((i8, N2) => i8 == this.active[N2]) && (I = this.active);
    let L = this.open, R = N.effects.some((i8) => i8.is(setActiveEffect));
    L && N.docChanged && (L = L.map(N.changes)), N.selection || I.some((i8) => i8.hasResult() && N.changes.touchesRange(i8.from, i8.to)) || !sameResults(I, this.active) || R ? L = CompletionDialog.build(I, P, this.id, L, F, R) : L && L.disabled && !I.some((i8) => i8.isPending) && (L = null), !L && I.every((i8) => !i8.isPending) && I.some((i8) => i8.hasResult()) && (I = I.map((i8) => i8.hasResult() ? new ActiveSource(i8.source, 0) : i8));
    for (let i8 of N.effects) i8.is(setSelectedEffect) && (L && (L = L.setSelected(i8.value, this.id)));
    return I == this.active && L == this.open ? this : new i2(I, this.id, L);
  }
  get tooltip() {
    return this.open ? this.open.tooltip : null;
  }
  get attrs() {
    return this.open ? this.open.attrs : this.active.length ? baseAttrs : noAttrs;
  }
};
function sameResults(i8, N) {
  if (i8 == N) return true;
  for (let P = 0, F = 0; ; ) {
    for (; P < i8.length && !i8[P].hasResult(); ) P++;
    for (; F < N.length && !N[F].hasResult(); ) F++;
    let I = P == i8.length, L = F == N.length;
    if (I || L) return I == L;
    if (i8[P++].result != N[F++].result) return false;
  }
}
var baseAttrs = { "aria-autocomplete": "list" }, noAttrs = {};
function makeAttrs(i8, N) {
  let P = {
    "aria-autocomplete": "list",
    "aria-haspopup": "listbox",
    "aria-controls": i8
  };
  return N > -1 && (P["aria-activedescendant"] = i8 + "-" + N), P;
}
var none = [];
function getUpdateType(i8, N) {
  if (i8.isUserEvent("input.complete")) {
    let P2 = i8.annotation(pickedCompletion);
    if (P2 && N.activateOnCompletion(P2)) return 12;
  }
  let P = i8.isUserEvent("input.type");
  return P && N.activateOnTyping ? 5 : P ? 1 : i8.isUserEvent("delete.backward") ? 2 : i8.selection ? 8 : i8.docChanged ? 16 : 0;
}
var ActiveSource = class i3 {
  constructor(i8, N, P = false) {
    this.source = i8, this.state = N, this.explicit = P;
  }
  hasResult() {
    return false;
  }
  get isPending() {
    return this.state == 1;
  }
  update(N, P) {
    let F = getUpdateType(N, P), I = this;
    (F & 8 || F & 16 && this.touches(N)) && (I = new i3(I.source, 0)), F & 4 && I.state == 0 && (I = new i3(this.source, 1)), I = I.updateFor(N, F);
    for (let P2 of N.effects) if (P2.is(startCompletionEffect)) I = new i3(I.source, 1, P2.value);
    else if (P2.is(closeCompletionEffect)) I = new i3(I.source, 0);
    else if (P2.is(setActiveEffect)) for (let i8 of P2.value) i8.source == I.source && (I = i8);
    return I;
  }
  updateFor(i8, N) {
    return this.map(i8.changes);
  }
  map(i8) {
    return this;
  }
  touches(i8) {
    return i8.changes.touchesRange(cur(i8.state));
  }
}, ActiveResult = class i4 extends ActiveSource {
  constructor(i8, N, P, F, I, L) {
    super(i8, 3, N), this.limit = P, this.result = F, this.from = I, this.to = L;
  }
  hasResult() {
    return true;
  }
  updateFor(N, P) {
    if (!(P & 3)) return this.map(N.changes);
    let F = this.result;
    F.map && !N.changes.empty && (F = F.map(F, N.changes));
    let I = N.changes.mapPos(this.from), L = N.changes.mapPos(this.to, 1), R = cur(N.state);
    if (R > L || !F || P & 2 && (cur(N.startState) == this.from || R < this.limit)) return new ActiveSource(this.source, P & 4 ? 1 : 0);
    let z = N.changes.mapPos(this.limit);
    return checkValid(F.validFor, N.state, I, L) ? new i4(this.source, this.explicit, z, F, I, L) : F.update && (F = F.update(F, I, L, new CompletionContext(N.state, R, false))) ? new i4(this.source, this.explicit, z, F, F.from, F.to ?? cur(N.state)) : new ActiveSource(this.source, 1, this.explicit);
  }
  map(N) {
    return N.empty ? this : (this.result.map ? this.result.map(this.result, N) : this.result) ? new i4(this.source, this.explicit, N.mapPos(this.limit), this.result, N.mapPos(this.from), N.mapPos(this.to, 1)) : new ActiveSource(this.source, 0);
  }
  touches(i8) {
    return i8.changes.touchesRange(this.from, this.to);
  }
};
function checkValid(i8, N, P, F) {
  if (!i8) return false;
  let I = N.sliceDoc(P, F);
  return typeof i8 == "function" ? i8(I, P, F, N) : ensureAnchor(i8, true).test(I);
}
var setActiveEffect = /* @__PURE__ */ StateEffect.define({ map(i8, N) {
  return i8.map((i9) => i9.map(N));
} }), completionState = /* @__PURE__ */ StateField.define({
  create() {
    return CompletionState.start();
  },
  update(i8, N) {
    return i8.update(N);
  },
  provide: (i8) => [showTooltip.from(i8, (i9) => i9.tooltip), EditorView.contentAttributes.from(i8, (i9) => i9.attrs)]
});
function applyCompletion(i8, N) {
  let P = N.completion.apply || N.completion.label, F = i8.state.field(completionState).active.find((i9) => i9.source == N.source);
  return F instanceof ActiveResult ? (typeof P == "string" ? i8.dispatch({
    ...insertCompletionText(i8.state, P, F.from, F.to),
    annotations: pickedCompletion.of(N.completion)
  }) : P(i8, N.completion, F.from, F.to), true) : false;
}
var createTooltip = /* @__PURE__ */ completionTooltip(completionState, applyCompletion);
function moveCompletionSelection(i8, N = "option") {
  return (P) => {
    let F = P.state.field(completionState, false);
    if (!F || !F.open || F.open.disabled || Date.now() - F.open.timestamp < P.state.facet(completionConfig).interactionDelay) return false;
    let I = 1, L;
    N == "page" && (L = getTooltip(P, F.open.tooltip)) && (I = Math.max(2, Math.floor(L.dom.offsetHeight / L.dom.querySelector("li").offsetHeight) - 1));
    let { length: R } = F.open.options, z = F.open.selected > -1 ? F.open.selected + I * (i8 ? 1 : -1) : i8 ? 0 : R - 1;
    return z < 0 ? z = N == "page" ? 0 : R - 1 : z >= R && (z = N == "page" ? R - 1 : 0), P.dispatch({ effects: setSelectedEffect.of(z) }), true;
  };
}
var acceptCompletion = (i8) => {
  let N = i8.state.field(completionState, false);
  return i8.state.readOnly || !N || !N.open || N.open.selected < 0 || N.open.disabled || Date.now() - N.open.timestamp < i8.state.facet(completionConfig).interactionDelay ? false : applyCompletion(i8, N.open.options[N.open.selected]);
}, startCompletion = (i8) => i8.state.field(completionState, false) ? (i8.dispatch({ effects: startCompletionEffect.of(true) }), true) : false, closeCompletion = (i8) => {
  let N = i8.state.field(completionState, false);
  return !N || !N.active.some((i9) => i9.state != 0) ? false : (i8.dispatch({ effects: closeCompletionEffect.of(null) }), true);
}, RunningQuery = class {
  constructor(i8, N) {
    this.active = i8, this.context = N, this.time = Date.now(), this.updates = [], this.done = void 0;
  }
}, MaxUpdateCount = 50, MinAbortTime = 1e3, completionPlugin = /* @__PURE__ */ ViewPlugin.fromClass(class {
  constructor(i8) {
    this.view = i8, this.debounceUpdate = -1, this.running = [], this.debounceAccept = -1, this.pendingStart = false, this.composing = 0;
    for (let N of i8.state.field(completionState).active) N.isPending && this.startQuery(N);
  }
  update(i8) {
    let N = i8.state.field(completionState), P = i8.state.facet(completionConfig);
    if (!i8.selectionSet && !i8.docChanged && i8.startState.field(completionState) == N) return;
    let F = i8.transactions.some((i9) => {
      let N2 = getUpdateType(i9, P);
      return N2 & 8 || (i9.selection || i9.docChanged) && !(N2 & 3);
    });
    for (let N2 = 0; N2 < this.running.length; N2++) {
      let P2 = this.running[N2];
      if (F || P2.context.abortOnDocChange && i8.docChanged || P2.updates.length + i8.transactions.length > MaxUpdateCount && Date.now() - P2.time > MinAbortTime) {
        for (let i9 of P2.context.abortListeners) try {
          i9();
        } catch (i10) {
          logException(this.view.state, i10);
        }
        P2.context.abortListeners = null, this.running.splice(N2--, 1);
      } else P2.updates.push(...i8.transactions);
    }
    this.debounceUpdate > -1 && clearTimeout(this.debounceUpdate), i8.transactions.some((i9) => i9.effects.some((i10) => i10.is(startCompletionEffect))) && (this.pendingStart = true);
    let I = this.pendingStart ? 50 : P.activateOnTypingDelay;
    if (this.debounceUpdate = N.active.some((i9) => i9.isPending && !this.running.some((N2) => N2.active.source == i9.source)) ? setTimeout(() => this.startUpdate(), I) : -1, this.composing != 0) for (let N2 of i8.transactions) N2.isUserEvent("input.type") ? this.composing = 2 : this.composing == 2 && N2.selection && (this.composing = 3);
  }
  startUpdate() {
    this.debounceUpdate = -1, this.pendingStart = false;
    let { state: i8 } = this.view, N = i8.field(completionState);
    for (let i9 of N.active) i9.isPending && !this.running.some((N2) => N2.active.source == i9.source) && this.startQuery(i9);
    this.running.length && N.open && N.open.disabled && (this.debounceAccept = setTimeout(() => this.accept(), this.view.state.facet(completionConfig).updateSyncTime));
  }
  startQuery(i8) {
    let { state: N } = this.view, P = new CompletionContext(N, cur(N), i8.explicit, this.view), F = new RunningQuery(i8, P);
    this.running.push(F), Promise.resolve(i8.source(P)).then((i9) => {
      F.context.aborted || (F.done = i9 || null, this.scheduleAccept());
    }, (i9) => {
      this.view.dispatch({ effects: closeCompletionEffect.of(null) }), logException(this.view.state, i9);
    });
  }
  scheduleAccept() {
    this.running.every((i8) => i8.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 i8 = [], N = this.view.state.facet(completionConfig), P = this.view.state.field(completionState);
    for (let F = 0; F < this.running.length; F++) {
      let I = this.running[F];
      if (I.done === void 0) continue;
      if (this.running.splice(F--, 1), I.done) {
        let P2 = cur(I.updates.length ? I.updates[0].startState : this.view.state), F2 = Math.min(P2, I.done.from + (I.active.explicit ? 0 : 1)), L2 = new ActiveResult(I.active.source, I.active.explicit, F2, I.done, I.done.from, I.done.to ?? P2);
        for (let i9 of I.updates) L2 = L2.update(i9, N);
        if (L2.hasResult()) {
          i8.push(L2);
          continue;
        }
      }
      let L = P.active.find((i9) => i9.source == I.active.source);
      if (L && L.isPending) if (I.done == null) {
        let P2 = new ActiveSource(I.active.source, 0);
        for (let i9 of I.updates) P2 = P2.update(i9, N);
        P2.isPending || i8.push(P2);
      } else this.startQuery(L);
    }
    (i8.length || P.open && P.open.disabled) && this.view.dispatch({ effects: setActiveEffect.of(i8) });
  }
}, { eventHandlers: {
  blur(i8) {
    let N = this.view.state.field(completionState, false);
    if (N && N.tooltip && this.view.state.facet(completionConfig).closeOnBlur) {
      let P = N.open && getTooltip(this.view, N.open.tooltip);
      (!P || !P.dom.contains(i8.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(i8, N) {
  let P = N.state.field(completionState, false);
  if (!P || !P.open || P.open.disabled || P.open.selected < 0 || i8.key.length > 1 || i8.ctrlKey && !(windows && i8.altKey) || i8.metaKey) return false;
  let F = P.open.options[P.open.selected], I = P.active.find((i9) => i9.source == F.source), L = F.completion.commitCharacters || I.result.commitCharacters;
  return L && L.indexOf(i8.key) > -1 && applyCompletion(N, F), 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(i8, N, P, F) {
    this.field = i8, this.line = N, this.from = P, this.to = F;
  }
}, FieldRange = class i5 {
  constructor(i8, N, P) {
    this.field = i8, this.from = N, this.to = P;
  }
  map(N) {
    let P = N.mapPos(this.from, -1, MapMode.TrackDel), F = N.mapPos(this.to, 1, MapMode.TrackDel);
    return P == null || F == null ? null : new i5(this.field, P, F);
  }
}, Snippet = class i6 {
  constructor(i8, N) {
    this.lines = i8, this.fieldPositions = N;
  }
  instantiate(i8, N) {
    let P = [], F = [N], I = i8.doc.lineAt(N), L = /^\s*/.exec(I.text)[0];
    for (let I2 of this.lines) {
      if (P.length) {
        let P2 = L, R = /^\t*/.exec(I2)[0].length;
        for (let N2 = 0; N2 < R; N2++) P2 += i8.facet(indentUnit);
        F.push(N + P2.length - R), I2 = P2 + I2.slice(R);
      }
      P.push(I2), N += I2.length + 1;
    }
    return {
      text: P,
      ranges: this.fieldPositions.map((i9) => new FieldRange(i9.field, F[i9.line] + i9.from, F[i9.line] + i9.to))
    };
  }
  static parse(N) {
    let P = [], F = [], I = [], L;
    for (let i8 of N.split(/\r\n?|\n/)) {
      for (; L = /[#$]\{(?:(\d+)(?::([^{}]*))?|((?:\\[{}]|[^{}])*))\}/.exec(i8); ) {
        let N2 = L[1] ? +L[1] : null, R = L[2] || L[3] || "", z = -1, B = R.replace(/\\[{}]/g, (i9) => i9[1]);
        for (let i9 = 0; i9 < P.length; i9++) (N2 == null ? B && P[i9].name == B : P[i9].seq == N2) && (z = i9);
        if (z < 0) {
          let i9 = 0;
          for (; i9 < P.length && (N2 == null || P[i9].seq != null && P[i9].seq < N2); ) i9++;
          P.splice(i9, 0, {
            seq: N2,
            name: B
          }), z = i9;
          for (let i10 of I) i10.field >= z && i10.field++;
        }
        for (let i9 of I) if (i9.line == F.length && i9.from > L.index) {
          let N3 = L[2] ? 3 + (L[1] || "").length : 2;
          i9.from -= N3, i9.to -= N3;
        }
        I.push(new FieldPos(z, F.length, L.index, L.index + B.length)), i8 = i8.slice(0, L.index) + R + i8.slice(L.index + L[0].length);
      }
      i8 = i8.replace(/\\([{}])/g, (i9, N2, P2) => {
        for (let i10 of I) i10.line == F.length && i10.from > P2 && (i10.from--, i10.to--);
        return N2;
      }), F.push(i8);
    }
    return new i6(F, I);
  }
}, fieldMarker = /* @__PURE__ */ Decoration.widget({ widget: /* @__PURE__ */ new class extends WidgetType {
  toDOM() {
    let i8 = document.createElement("span");
    return i8.className = "cm-snippetFieldPosition", i8;
  }
  ignoreEvent() {
    return false;
  }
}() }), fieldRange = /* @__PURE__ */ Decoration.mark({ class: "cm-snippetField" }), ActiveSnippet = class i7 {
  constructor(i8, N) {
    this.ranges = i8, this.active = N, this.deco = Decoration.set(i8.map((i9) => (i9.from == i9.to ? fieldMarker : fieldRange).range(i9.from, i9.to)), true);
  }
  map(N) {
    let P = [];
    for (let i8 of this.ranges) {
      let F = i8.map(N);
      if (!F) return null;
      P.push(F);
    }
    return new i7(P, this.active);
  }
  selectionInsideField(i8) {
    return i8.ranges.every((i9) => this.ranges.some((N) => N.field == this.active && N.from <= i9.from && N.to >= i9.to));
  }
}, setActive = /* @__PURE__ */ StateEffect.define({ map(i8, N) {
  return i8 && i8.map(N);
} }), moveToField = /* @__PURE__ */ StateEffect.define(), snippetState = /* @__PURE__ */ StateField.define({
  create() {
    return null;
  },
  update(i8, N) {
    for (let P of N.effects) {
      if (P.is(setActive)) return P.value;
      if (P.is(moveToField) && i8) return new ActiveSnippet(i8.ranges, P.value);
    }
    return i8 && N.docChanged && (i8 = i8.map(N.changes)), i8 && N.selection && !i8.selectionInsideField(N.selection) && (i8 = null), i8;
  },
  provide: (i8) => EditorView.decorations.from(i8, (i9) => i9 ? i9.deco : Decoration.none)
});
function fieldSelection(i8, N) {
  return EditorSelection.create(i8.filter((i9) => i9.field == N).map((i9) => EditorSelection.range(i9.from, i9.to)));
}
function snippet(i8) {
  let N = Snippet.parse(i8);
  return (i9, P, F, I) => {
    let { text: L, ranges: B } = N.instantiate(i9.state, F), { main: V } = i9.state.selection, U = {
      changes: {
        from: F,
        to: I == V.from ? V.to : I,
        insert: Text.of(L)
      },
      scrollIntoView: true,
      annotations: P ? [pickedCompletion.of(P), Transaction.userEvent.of("input.complete")] : void 0
    };
    if (B.length && (U.selection = fieldSelection(B, 0)), B.some((i10) => i10.field > 0)) {
      let N2 = new ActiveSnippet(B, 0), P2 = U.effects = [setActive.of(N2)];
      i9.state.field(snippetState, false) === void 0 && P2.push(StateEffect.appendConfig.of([
        snippetState,
        addSnippetKeymap,
        snippetPointerHandler,
        baseTheme
      ]));
    }
    i9.dispatch(i9.state.update(U));
  };
}
function moveField(i8) {
  return ({ state: N, dispatch: P }) => {
    let F = N.field(snippetState, false);
    if (!F || i8 < 0 && F.active == 0) return false;
    let I = F.active + i8, L = i8 > 0 && !F.ranges.some((N2) => N2.field == I + i8);
    return P(N.update({
      selection: fieldSelection(F.ranges, I),
      effects: setActive.of(L ? null : new ActiveSnippet(F.ranges, I)),
      scrollIntoView: true
    })), true;
  };
}
var defaultSnippetKeymap = [{
  key: "Tab",
  run: /* @__PURE__ */ moveField(1),
  shift: /* @__PURE__ */ moveField(-1)
}, {
  key: "Escape",
  run: ({ state: i8, dispatch: N }) => i8.field(snippetState, false) ? (N(i8.update({ effects: setActive.of(null) })), true) : false
}], snippetKeymap = /* @__PURE__ */ Facet.define({ combine(i8) {
  return i8.length ? i8[0] : defaultSnippetKeymap;
} }), addSnippetKeymap = /* @__PURE__ */ Prec.highest(/* @__PURE__ */ keymap.compute([snippetKeymap], (i8) => i8.facet(snippetKeymap)));
function snippetCompletion(i8, N) {
  return {
    ...N,
    apply: snippet(i8)
  };
}
var snippetPointerHandler = /* @__PURE__ */ EditorView.domEventHandlers({ mousedown(i8, N) {
  let P = N.state.field(snippetState, false), F;
  if (!P || (F = N.posAtCoords({
    x: i8.clientX,
    y: i8.clientY
  })) == null) return false;
  let I = P.ranges.find((i9) => i9.from <= F && i9.to >= F);
  return !I || I.field == P.active ? false : (N.dispatch({
    selection: fieldSelection(P.ranges, I.field),
    effects: setActive.of(P.ranges.some((i9) => i9.field > I.field) ? new ActiveSnippet(P.ranges, I.field) : null),
    scrollIntoView: true
  }), true);
} }), defaults = {
  brackets: [
    "(",
    "[",
    "{",
    "'",
    '"'
  ],
  before: ")]}:;>",
  stringPrefixes: []
}, closeBracketEffect = /* @__PURE__ */ StateEffect.define({ map(i8, N) {
  return N.mapPos(i8, -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(i8, N) {
    if (i8 = i8.map(N.changes), N.selection) {
      let P = N.state.doc.lineAt(N.selection.main.head);
      i8 = i8.update({ filter: (i9) => i9 >= P.from && i9 <= P.to });
    }
    for (let P of N.effects) P.is(closeBracketEffect) && (i8 = i8.update({ add: [closedBracket.range(P.value, P.value + 1)] }));
    return i8;
  }
});
function closeBrackets() {
  return [inputHandler, bracketState];
}
var definedClosing = "()[]{}<>\xAB\xBB\xBB\xAB\uFF3B\uFF3D\uFF5B\uFF5D";
function closing(i8) {
  for (let N = 0; N < 16; N += 2) if (definedClosing.charCodeAt(N) == i8) return definedClosing.charAt(N + 1);
  return fromCodePoint(i8 < 128 ? i8 : i8 + 1);
}
function config(i8, N) {
  return i8.languageDataAt("closeBrackets", N)[0] || defaults;
}
var android = typeof navigator == "object" && /* @__PURE__ */ /Android\b/.test(navigator.userAgent), inputHandler = /* @__PURE__ */ EditorView.inputHandler.of((i8, N, P, F) => {
  if ((android ? i8.composing : i8.compositionStarted) || i8.state.readOnly) return false;
  let I = i8.state.selection.main;
  if (F.length > 2 || F.length == 2 && codePointSize(codePointAt(F, 0)) == 1 || N != I.from || P != I.to) return false;
  let L = insertBracket(i8.state, F);
  return L ? (i8.dispatch(L), true) : false;
}), closeBracketsKeymap = [{
  key: "Backspace",
  run: ({ state: i8, dispatch: N }) => {
    if (i8.readOnly) return false;
    let P = config(i8, i8.selection.main.head).brackets || defaults.brackets, I = null, L = i8.changeByRange((N2) => {
      if (N2.empty) {
        let I2 = prevChar(i8.doc, N2.head);
        for (let L2 of P) if (L2 == I2 && nextChar(i8.doc, N2.head) == closing(codePointAt(L2, 0))) return {
          changes: {
            from: N2.head - L2.length,
            to: N2.head + L2.length
          },
          range: EditorSelection.cursor(N2.head - L2.length)
        };
      }
      return { range: I = N2 };
    });
    return I || N(i8.update(L, {
      scrollIntoView: true,
      userEvent: "delete.backward"
    })), !I;
  }
}];
function insertBracket(i8, N) {
  let P = config(i8, i8.selection.main.head), F = P.brackets || defaults.brackets;
  for (let I of F) {
    let L = closing(codePointAt(I, 0));
    if (N == I) return L == I ? handleSame(i8, I, F.indexOf(I + I + I) > -1, P) : handleOpen(i8, I, L, P.before || defaults.before);
    if (N == L && closedBracketAt(i8, i8.selection.main.from)) return handleClose(i8, I, L);
  }
  return null;
}
function closedBracketAt(i8, N) {
  let P = false;
  return i8.field(bracketState).between(0, i8.doc.length, (i9) => {
    i9 == N && (P = true);
  }), P;
}
function nextChar(i8, N) {
  let P = i8.sliceString(N, N + 2);
  return P.slice(0, codePointSize(codePointAt(P, 0)));
}
function prevChar(i8, N) {
  let P = i8.sliceString(N - 2, N);
  return codePointSize(codePointAt(P, 0)) == P.length ? P : P.slice(1);
}
function handleOpen(i8, N, P, I) {
  let L = null, R = i8.changeByRange((R2) => {
    if (!R2.empty) return {
      changes: [{
        insert: N,
        from: R2.from
      }, {
        insert: P,
        from: R2.to
      }],
      effects: closeBracketEffect.of(R2.to + N.length),
      range: EditorSelection.range(R2.anchor + N.length, R2.head + N.length)
    };
    let z = nextChar(i8.doc, R2.head);
    return !z || /\s/.test(z) || I.indexOf(z) > -1 ? {
      changes: {
        insert: N + P,
        from: R2.head
      },
      effects: closeBracketEffect.of(R2.head + N.length),
      range: EditorSelection.cursor(R2.head + N.length)
    } : { range: L = R2 };
  });
  return L ? null : i8.update(R, {
    scrollIntoView: true,
    userEvent: "input.type"
  });
}
function handleClose(i8, N, P) {
  let I = null, L = i8.changeByRange((N2) => N2.empty && nextChar(i8.doc, N2.head) == P ? {
    changes: {
      from: N2.head,
      to: N2.head + P.length,
      insert: P
    },
    range: EditorSelection.cursor(N2.head + P.length)
  } : I = { range: N2 });
  return I ? null : i8.update(L, {
    scrollIntoView: true,
    userEvent: "input.type"
  });
}
function handleSame(i8, N, P, I) {
  let L = I.stringPrefixes || defaults.stringPrefixes, R = null, z = i8.changeByRange((I2) => {
    if (!I2.empty) return {
      changes: [{
        insert: N,
        from: I2.from
      }, {
        insert: N,
        from: I2.to
      }],
      effects: closeBracketEffect.of(I2.to + N.length),
      range: EditorSelection.range(I2.anchor + N.length, I2.head + N.length)
    };
    let z2 = I2.head, B = nextChar(i8.doc, z2), V;
    if (B == N) {
      if (nodeStart(i8, z2)) return {
        changes: {
          insert: N + N,
          from: z2
        },
        effects: closeBracketEffect.of(z2 + N.length),
        range: EditorSelection.cursor(z2 + N.length)
      };
      if (closedBracketAt(i8, z2)) {
        let I3 = P && i8.sliceDoc(z2, z2 + N.length * 3) == N + N + N ? N + N + N : N;
        return {
          changes: {
            from: z2,
            to: z2 + I3.length,
            insert: I3
          },
          range: EditorSelection.cursor(z2 + I3.length)
        };
      }
    } else if (P && i8.sliceDoc(z2 - 2 * N.length, z2) == N + N && (V = canStartStringAt(i8, z2 - 2 * N.length, L)) > -1 && nodeStart(i8, V)) return {
      changes: {
        insert: N + N + N + N,
        from: z2
      },
      effects: closeBracketEffect.of(z2 + N.length),
      range: EditorSelection.cursor(z2 + N.length)
    };
    else if (i8.charCategorizer(z2)(B) != CharCategory.Word && canStartStringAt(i8, z2, L) > -1 && !probablyInString(i8, z2, N, L)) return {
      changes: {
        insert: N + N,
        from: z2
      },
      effects: closeBracketEffect.of(z2 + N.length),
      range: EditorSelection.cursor(z2 + N.length)
    };
    return { range: R = I2 };
  });
  return R ? null : i8.update(z, {
    scrollIntoView: true,
    userEvent: "input.type"
  });
}
function nodeStart(i8, N) {
  let P = syntaxTree(i8).resolveInner(N + 1);
  return P.parent && P.from == N;
}
function probablyInString(i8, N, P, F) {
  let I = syntaxTree(i8).resolveInner(N, -1), R = F.reduce((i9, N2) => Math.max(i9, N2.length), 0);
  for (let L = 0; L < 5; L++) {
    let L2 = i8.sliceDoc(I.from, Math.min(I.to, I.from + P.length + R)), z = L2.indexOf(P);
    if (!z || z > -1 && F.indexOf(L2.slice(0, z)) > -1) {
      let N2 = I.firstChild;
      for (; N2 && N2.from == I.from && N2.to - N2.from > P.length + z; ) {
        if (i8.sliceDoc(N2.to - P.length, N2.to) == P) return false;
        N2 = N2.firstChild;
      }
      return true;
    }
    let B = I.to == N && I.parent;
    if (!B) break;
    I = B;
  }
  return false;
}
function canStartStringAt(i8, N, P) {
  let F = i8.charCategorizer(N);
  if (F(i8.sliceDoc(N - 1, N)) != CharCategory.Word) return N;
  for (let I of P) {
    let P2 = N - I.length;
    if (i8.sliceDoc(P2, N) == I && F(i8.sliceDoc(P2 - 1, P2)) != CharCategory.Word) return P2;
  }
  return -1;
}
function autocompletion(i8 = {}) {
  return [
    commitCharacters,
    completionState,
    completionConfig.of(i8),
    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], (i8) => i8.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
};
