(function initMyronRichtextToolbar(global) {
  "use strict";

  var commands = [
    ["bold", "Bold", "B", "bold", false, "bold"],
    ["italic", "Italic", "I", "italic", false, "italic"],
    ["insertUnorderedList", "Unordered list", "UL", "list", true, "list-ul"],
    ["insertOrderedList", "Ordered list", "OL", "list", true, "list-ol"],
    ["alignStart", "Align start", "Start", "align", true, "align-start"],
    ["alignCenter", "Align center", "Center", "align", true, "align-center"],
    ["alignEnd", "Align end", "End", "align", true, "align-end"],
    ["createLink", "Insert link", "Link", "insert", false, "link"],
    ["insertTable", "Insert table", "Table", "insert", true, "table"],
    ["inlineCode", "Inline code", "Code", "code", false, "code"],
    ["strikeThrough", "Strikethrough", "S", "strikeThrough", false, "strike"],
    ["superscript", "Superscript", "Sup", "superscript", false, "sup"],
    ["subscript", "Subscript", "Sub", "subscript", false, "sub"]
  ];

  var tableCommands = [
    ["tableRowAbove", "Add row above", "Row +", "row-above"],
    ["tableRowBelow", "Add row below", "+ Row", "row-below"],
    ["tableDeleteRow", "Delete row", "Row -", "row-delete"],
    ["tableColumnLeft", "Add column left", "Col +", "col-left"],
    ["tableColumnRight", "Add column right", "+ Col", "col-right"],
    ["tableDeleteColumn", "Delete column", "Col -", "col-delete"],
    ["tableDelete", "Delete table", "Table -", "table-delete"]
  ];

  var iconPaths = {
    "list-ul": '<path d="M7 6h12"/><path d="M7 12h12"/><path d="M7 18h12"/><path d="M4 6h.01"/><path d="M4 12h.01"/><path d="M4 18h.01"/>',
    "list-ol": '<path d="M10 6h9"/><path d="M10 12h9"/><path d="M10 18h9"/><path d="M4 6h1v4"/><path d="M4 10h2"/><path d="M4 14h2l-2 4h2"/>',
    "align-start": '<path d="M4 6h16"/><path d="M4 10h10"/><path d="M4 14h16"/><path d="M4 18h10"/>',
    "align-center": '<path d="M4 6h16"/><path d="M7 10h10"/><path d="M4 14h16"/><path d="M7 18h10"/>',
    "align-end": '<path d="M4 6h16"/><path d="M10 10h10"/><path d="M4 14h16"/><path d="M10 18h10"/>',
    link: '<path d="M10 13a5 5 0 0 0 7.07 0l2-2a5 5 0 0 0-7.07-7.07l-1.15 1.15"/><path d="M14 11a5 5 0 0 0-7.07 0l-2 2A5 5 0 0 0 12 20.07l1.15-1.15"/>',
    table: '<path d="M4 5h16v14H4z"/><path d="M4 10h16"/><path d="M9 5v14"/><path d="M15 5v14"/>',
    "row-above": '<path d="M4 5h16v5H4z"/><path d="M4 14h16v5H4z"/><path d="M12 11v-4"/><path d="m9 8 3-3 3 3"/>',
    "row-below": '<path d="M4 5h16v5H4z"/><path d="M4 14h16v5H4z"/><path d="M12 13v4"/><path d="m9 16 3 3 3-3"/>',
    "row-delete": '<path d="M4 5h16v5H4z"/><path d="M4 14h16v5H4z"/><path d="M8 12h8"/>',
    "col-left": '<path d="M4 5h7v14H4z"/><path d="M15 5h5v14h-5z"/><path d="M13 12H9"/><path d="m10 9-3 3 3 3"/>',
    "col-right": '<path d="M4 5h5v14H4z"/><path d="M13 5h7v14h-7z"/><path d="M11 12h4"/><path d="m14 9 3 3-3 3"/>',
    "col-delete": '<path d="M4 5h6v14H4z"/><path d="M14 5h6v14h-6z"/><path d="M11 12h2"/>',
    "table-delete": '<path d="M4 5h16v14H4z"/><path d="M4 10h16"/><path d="M9 5v14"/><path d="M15 5v14"/><path d="m8 8 8 8"/><path d="m16 8-8 8"/>',
    code: '<path d="m9 18-6-6 6-6"/><path d="m15 6 6 6-6 6"/>'
  };

  function setupRichtextToolbar(rootElement) {
    var root = rootElement || global.document;
    var toolbarSlot = root.querySelector("[data-mc-richtext-toolbar]");
    var controls = Array.prototype.slice.call(root.querySelectorAll("[data-mc-richtext]"));
    var active = null;
    var mode = "visual";
    var disposers = [];
    var micTypesCache = null;
    var micPicker = null;
    var tableContext = null;

    if (!toolbarSlot || !controls.length) {
      return { destroy: function noop() {} };
    }

    function syncSurface(entry) {
      if (!entry || !entry.surface || !entry.control) {
        return;
      }
      serializeMicPills(entry.surface);
      if (entry.singleLine) {
        entry.control.value = entry.surface.innerHTML.replace(/<div><br><\/div>/g, "");
      } else {
        entry.control.value = entry.surface.innerHTML;
      }
    }

    function syncFromControl(entry) {
      if (!entry || !entry.surface || !entry.control) {
        return;
      }
      entry.surface.innerHTML = entry.control.value || "";
      renderMicPills(entry.surface);
    }

    function makeSurface(control) {
      var singleLine = control.getAttribute("data-mc-richtext-singleline") === "true" || control.tagName.toLowerCase() === "input";
      var surface = global.document.createElement("div");
      surface.className = "mc-richtext-surface" + (singleLine ? " mc-richtext-surface--singleline" : "");
      surface.contentEditable = "true";
      surface.setAttribute("role", "textbox");
      surface.setAttribute("aria-multiline", singleLine ? "false" : "true");
      surface.innerHTML = control.value || "";
      control.classList.add("mc-richtext-source");
      control.parentNode.insertBefore(surface, control.nextSibling);

      var micAttr = control.getAttribute("data-mc-richtext-mics") || "";
      var mics = micAttr.split(",").map(function trimMic(value) { return value.trim(); }).filter(Boolean);
      var entry = { control: control, surface: surface, singleLine: singleLine, mics: mics };
      control.hidden = true;
      surface.addEventListener("focus", function onSurfaceFocus() {
        active = entry;
        updateButtons();
      });
      surface.addEventListener("mouseup", updateButtons);
      surface.addEventListener("keyup", updateButtons);
      surface.addEventListener("input", function onSurfaceInput() {
        syncSurface(entry);
        if (mode === "visual") {
          renderMicPills(entry.surface);
        }
        updateButtons();
      });
      surface.addEventListener("keydown", function onSurfaceKeydown(event) {
        if (event.key !== "Backspace") {
          return;
        }
        var selection = global.getSelection();
        if (!selection || selection.rangeCount === 0 || !selection.isCollapsed) {
          return;
        }
        var range = selection.getRangeAt(0);
        var node = range.startContainer;
        var offset = range.startOffset;
        if (node && node.nodeType === 3 && offset === 0) {
          node = node.previousSibling || node.parentNode.previousSibling;
        } else if (node && node.nodeType === 1) {
          node = node.childNodes[Math.max(0, offset - 1)];
        }
        if (node && node.nodeType === 1 && node.classList.contains("mc-mic-pill")) {
          event.preventDefault();
          node.remove();
          syncSurface(entry);
        }
      });
      control.addEventListener("focus", function onControlFocus() {
        active = entry;
        updateButtons();
      });
      control.form && control.form.addEventListener("submit", function onSubmit() {
        syncSurface(entry);
      });
      disposers.push(function destroySurface() {
        syncSurface(entry);
        control.hidden = false;
        control.classList.remove("mc-richtext-source");
        if (surface.parentNode) {
          surface.parentNode.removeChild(surface);
        }
      });

      return entry;
    }

    var entries = controls.map(makeSurface);

    function onSelectionChange() {
      if (!active || mode === "html") {
        return;
      }
      updateButtons();
    }
    global.document.addEventListener("selectionchange", onSelectionChange);
    disposers.push(function destroySelectionChange() {
      global.document.removeEventListener("selectionchange", onSelectionChange);
    });

    function escapeHtml(value) {
      return String(value || "").replace(/[&<>"']/g, function replaceChar(char) {
        return { "&": "&amp;", "<": "&lt;", ">": "&gt;", "\"": "&quot;", "'": "&#039;" }[char];
      });
    }

    function commandIcon(name, fallback) {
      var escapedFallback = escapeHtml(fallback || "");
      if (iconPaths[name]) {
        return '<svg class="mc-richtext-toolbar__icon" aria-hidden="true" focusable="false" viewBox="0 0 24 24">' + iconPaths[name] + '</svg>';
      }
      return '<span class="mc-richtext-toolbar__glyph" aria-hidden="true">' + escapedFallback + '</span>';
    }

    function renderMicPills(surface) {
      if (!surface || mode === "html") {
        return;
      }
      var html = surface.innerHTML || "";
      html = html.replace(/\[mic-([a-z0-9._-]+)-(mic_[a-f0-9]{16})\]/g, function replaceToken(token, type, id) {
        return '<span class="mc-mic-pill" contenteditable="false" data-mic-token="' + escapeHtml(token) + '" data-mic-type="' + escapeHtml(type) + '" data-mic-id="' + escapeHtml(id) + '" title="' + escapeHtml(token) + '">' + escapeHtml(type) + ' ' + escapeHtml(id) + '</span>';
      });
      if (html !== surface.innerHTML) {
        surface.innerHTML = html;
      }
      surface.querySelectorAll(".mc-mic-pill").forEach(function bindPill(pill) {
        if (pill.getAttribute("data-mic-bound") === "true") {
          return;
        }
        pill.setAttribute("data-mic-bound", "true");
        pill.addEventListener("click", function onPillClick(event) {
          event.preventDefault();
          surface.querySelectorAll(".mc-mic-pill.is-selected").forEach(function clear(other) { other.classList.remove("is-selected"); });
          pill.classList.add("is-selected");
        });
        pill.addEventListener("dblclick", function onPillDblClick(event) {
          event.preventDefault();
          var type = pill.getAttribute("data-mic-type") || "";
          var id = pill.getAttribute("data-mic-id") || "";
          if (type === "table" && id) {
            global.location.href = "/admin/content/content-banks?bank=tables&edit=" + encodeURIComponent(id);
          }
        });
      });
    }

    function serializeMicPills(surface) {
      if (!surface) {
        return;
      }
      surface.querySelectorAll(".mc-mic-pill").forEach(function replacePill(pill) {
        var token = pill.getAttribute("data-mic-token") || "";
        pill.replaceWith(global.document.createTextNode(token));
      });
    }

    function updateMode(nextMode) {
      mode = nextMode === "html" ? "html" : "visual";
      entries.forEach(function syncEntry(entry) {
        if (mode === "html") {
          syncSurface(entry);
          entry.surface.hidden = true;
          entry.control.hidden = false;
          entry.control.classList.add("mc-richtext-html-source");
        } else {
          syncFromControl(entry);
          entry.control.hidden = true;
          entry.control.classList.remove("mc-richtext-html-source");
          entry.surface.hidden = false;
        }
      });
      toolbarSlot.querySelectorAll("[data-mc-richtext-mode]").forEach(function syncButton(button) {
        button.setAttribute("aria-pressed", button.getAttribute("data-mc-richtext-mode") === mode ? "true" : "false");
      });
    }

    function wrapSelection(tagName) {
      if (!active) {
        return;
      }
      var selection = global.getSelection();
      if (!selection || selection.rangeCount === 0) {
        return;
      }
      var range = selection.getRangeAt(0);
      var element = global.document.createElement(tagName);
      try {
        range.surroundContents(element);
      } catch (error) {
        element.appendChild(range.extractContents());
        range.insertNode(element);
      }
      syncSurface(active);
    }

    function applyAlignment(className) {
      if (!active || active.singleLine) {
        return;
      }
      var selection = global.getSelection();
      var node = selection && selection.anchorNode ? selection.anchorNode : active.surface;
      var element = node.nodeType === 1 ? node : node.parentElement;
      while (element && element !== active.surface && element.tagName.toLowerCase() !== "p") {
        element = element.parentElement;
      }
      if (!element || element === active.surface) {
        element = global.document.createElement("p");
        element.innerHTML = active.surface.innerHTML || "<br>";
        active.surface.innerHTML = "";
        active.surface.appendChild(element);
      }
      element.classList.remove("myron-align--start", "myron-align--center", "myron-align--end");
      element.classList.add(className);
      syncSurface(active);
    }

    function normalizeLinkHref(value) {
      var href = String(value || "").trim();
      if (!href) {
        return "";
      }
      if (/^(https?:|mailto:|tel:)/i.test(href) || href.charAt(0) === "/" || href.charAt(0) === "#") {
        return href;
      }
      if (/^[a-z][a-z0-9+.-]*:/i.test(href)) {
        return "";
      }
      return "https://" + href;
    }

    function applyLink() {
      if (!active) {
        return;
      }
      var selection = global.getSelection();
      var selectedText = selection && String(selection).trim() ? String(selection).trim() : "";
      var promptValue = global.prompt("Link URL", selectedText ? "https://" : "");
      var href = normalizeLinkHref(promptValue);
      if (!href) {
        return;
      }
      global.document.execCommand("createLink", false, href);
      active.surface.querySelectorAll("a[href]").forEach(function hardenLink(link) {
        link.setAttribute("rel", "noopener");
      });
      syncSurface(active);
    }

    function insertTable() {
      if (!active || active.singleLine) {
        return;
      }
      var table = global.document.createElement("table");
      var thead = global.document.createElement("thead");
      var tbody = global.document.createElement("tbody");
      var headerRow = global.document.createElement("tr");
      ["Header", "Header"].forEach(function appendHeader(text) {
        var th = global.document.createElement("th");
        th.textContent = text;
        headerRow.appendChild(th);
      });
      thead.appendChild(headerRow);
      for (var rowIndex = 0; rowIndex < 2; rowIndex += 1) {
        var row = global.document.createElement("tr");
        for (var columnIndex = 0; columnIndex < 2; columnIndex += 1) {
          var cell = global.document.createElement("td");
          cell.appendChild(global.document.createElement("br"));
          row.appendChild(cell);
        }
        tbody.appendChild(row);
      }
      table.appendChild(thead);
      table.appendChild(tbody);
      var range = currentSelectionRange();
      if (!range) {
        active.surface.appendChild(table);
      } else {
        range.deleteContents();
        range.insertNode(table);
        range.setStartAfter(table);
        range.setEndAfter(table);
        var nextSelection = global.getSelection();
        nextSelection.removeAllRanges();
        nextSelection.addRange(range);
      }
      syncSurface(active);
      focusCell(table.querySelector("tbody td") || table.querySelector("td, th"));
      updateButtons();
    }

    function findClosestTableContext(node) {
      if (!active || active.singleLine || mode === "html" || !node) {
        return null;
      }
      var element = node.nodeType === 1 ? node : node.parentElement;
      if (!element || !active.surface.contains(element)) {
        return null;
      }
      var cell = element.closest ? element.closest("td, th") : null;
      if (!cell || !active.surface.contains(cell)) {
        return null;
      }
      var row = cell.closest ? cell.closest("tr") : null;
      var table = cell.closest ? cell.closest("table") : null;
      if (!row || !table || !active.surface.contains(table)) {
        return null;
      }
      return { table: table, row: row, cell: cell };
    }

    function currentTableContext() {
      var selection = global.getSelection();
      var context = selection && selection.anchorNode ? findClosestTableContext(selection.anchorNode) : null;
      if (context) {
        tableContext = context;
      }
      return context;
    }

    function usableTableContext() {
      var context = currentTableContext() || tableContext;
      if (!context || !context.table || !active || !active.surface.contains(context.table)) {
        return null;
      }
      return context;
    }

    function cellTagForRow(row) {
      return row && row.querySelector("th") ? "th" : "td";
    }

    function createEmptyCell(tagName) {
      var cell = global.document.createElement(tagName || "td");
      cell.appendChild(global.document.createElement("br"));
      return cell;
    }

    function cloneEmptyRowFrom(row) {
      var nextRow = global.document.createElement("tr");
      var cells = Array.prototype.slice.call(row ? row.children : []);
      if (!cells.length) {
        cells = [createEmptyCell("td"), createEmptyCell("td")];
      }
      cells.forEach(function appendCell(cell) {
        nextRow.appendChild(createEmptyCell(cell.tagName ? cell.tagName.toLowerCase() : "td"));
      });
      return nextRow;
    }

    function cellIndex(cell) {
      return Array.prototype.indexOf.call(cell.parentNode.children, cell);
    }

    function focusCell(cell) {
      if (!cell) {
        return;
      }
      active.surface.focus();
      var range = global.document.createRange();
      range.selectNodeContents(cell);
      range.collapse(true);
      var selection = global.getSelection();
      selection.removeAllRanges();
      selection.addRange(range);
      tableContext = findClosestTableContext(cell);
    }

    function runTableCommand(command) {
      if (!active || active.singleLine || mode === "html") {
        return;
      }
      var context = usableTableContext();
      if (!context) {
        return;
      }
      var targetCell = context.cell;
      if (command === "tableRowAbove") {
        var above = cloneEmptyRowFrom(context.row);
        context.row.parentNode.insertBefore(above, context.row);
        targetCell = above.children[Math.min(cellIndex(context.cell), above.children.length - 1)] || above.children[0] || null;
      } else if (command === "tableRowBelow") {
        var below = cloneEmptyRowFrom(context.row);
        context.row.parentNode.insertBefore(below, context.row.nextSibling);
        targetCell = below.children[Math.min(cellIndex(context.cell), below.children.length - 1)] || below.children[0] || null;
      } else if (command === "tableDeleteRow") {
        var nextRow = context.row.nextElementSibling || context.row.previousElementSibling;
        context.row.remove();
        if (!context.table.querySelector("tr")) {
          context.table.remove();
          targetCell = null;
        } else {
          targetCell = nextRow ? nextRow.children[Math.min(cellIndex(context.cell), nextRow.children.length - 1)] || nextRow.children[0] : null;
          targetCell = targetCell || context.table.querySelector("td, th");
        }
      } else if (command === "tableColumnLeft" || command === "tableColumnRight") {
        var index = cellIndex(context.cell);
        var insertAfter = command === "tableColumnRight";
        context.table.querySelectorAll("tr").forEach(function insertColumn(row) {
          var reference = row.children[Math.min(index, row.children.length - 1)] || null;
          var newCell = createEmptyCell(cellTagForRow(row));
          if (!reference) {
            row.appendChild(newCell);
          } else if (insertAfter) {
            row.insertBefore(newCell, reference.nextSibling);
          } else {
            row.insertBefore(newCell, reference);
          }
          if (row === context.row) {
            targetCell = newCell;
          }
        });
      } else if (command === "tableDeleteColumn") {
        var deleteIndex = cellIndex(context.cell);
        var focusIndex = Math.max(0, deleteIndex - 1);
        context.table.querySelectorAll("tr").forEach(function deleteColumn(row) {
          if (row.children[deleteIndex]) {
            row.children[deleteIndex].remove();
          }
        });
        if (!context.table.querySelector("td, th")) {
          context.table.remove();
          targetCell = null;
        } else {
          targetCell = context.row.children[Math.min(focusIndex, context.row.children.length - 1)] || context.table.querySelector("td, th");
        }
      } else if (command === "tableDelete") {
        context.table.remove();
        targetCell = null;
      }
      if (targetCell) {
        focusCell(targetCell);
      } else {
        tableContext = null;
      }
      syncSurface(active);
      updateButtons();
    }

    function runCommand(command) {
      if (!active) {
        active = entries[0] || null;
      }
      if (!active) {
        return;
      }
      if (mode === "html") {
        updateMode("visual");
      }
      active.surface.focus();
      if (command === "inlineCode") {
        wrapSelection("code");
      } else if (command === "alignStart") {
        applyAlignment("myron-align--start");
      } else if (command === "alignCenter") {
        applyAlignment("myron-align--center");
      } else if (command === "alignEnd") {
        applyAlignment("myron-align--end");
      } else if (command === "createLink") {
        applyLink();
      } else if (command === "insertTable") {
        insertTable();
      } else if (command.indexOf("table") === 0 && command !== "table") {
        runTableCommand(command);
      } else {
        global.document.execCommand(command, false, null);
        syncSurface(active);
      }
      updateButtons();
    }

    function updateButtons() {
      var singleLine = Boolean(active && active.singleLine);
      var hasTableContext = Boolean(currentTableContext());
      toolbarSlot.querySelectorAll("[data-mc-richtext-block]").forEach(function syncBlockButton(button) {
        button.disabled = singleLine;
      });
      toolbarSlot.querySelectorAll("[data-mc-richtext-table-button]").forEach(function syncTableButton(button) {
        button.disabled = mode === "html" || singleLine || !hasTableContext;
      });
      toolbarSlot.querySelectorAll("[data-mc-richtext-table-tools]").forEach(function syncTableGroup(group) {
        group.hidden = !hasTableContext;
      });
      toolbarSlot.querySelectorAll("[data-mc-richtext-mic-button]").forEach(function syncMicButton(button) {
        button.disabled = mode === "html" || singleLine || !active || !active.mics || active.mics.length === 0;
      });
    }

    function currentSelectionRange() {
      var selection = global.getSelection();
      if (!selection || selection.rangeCount === 0) {
        return null;
      }
      return selection.getRangeAt(0);
    }

    function insertTextAtCursor(text) {
      if (!active || !text) {
        return;
      }
      active.surface.focus();
      var range = currentSelectionRange();
      if (!range) {
        active.surface.appendChild(global.document.createTextNode(text));
      } else {
        range.deleteContents();
        var node = global.document.createTextNode(text);
        range.insertNode(node);
        range.setStartAfter(node);
        range.setEndAfter(node);
        var selection = global.getSelection();
        selection.removeAllRanges();
        selection.addRange(range);
      }
      syncSurface(active);
      syncFromControl(active);
      updateButtons();
    }

    function ensureMicPicker() {
      if (micPicker) {
        return micPicker;
      }
      micPicker = global.document.createElement("div");
      micPicker.className = "mc-richtext-toolbar__mic-picker";
      micPicker.hidden = true;
      toolbarSlot.appendChild(micPicker);
      return micPicker;
    }

    function loadMicTypes() {
      if (micTypesCache) {
        return Promise.resolve(micTypesCache);
      }
      return fetch("/admin/api/v1/content/mics/types", { credentials: "same-origin" })
        .then(function parse(response) { return response.json(); })
        .then(function cache(payload) {
          micTypesCache = (payload && payload.result && payload.result.types) || [];
          return micTypesCache;
        })
        .catch(function fallback() {
          micTypesCache = [{ slug: "table", label: "Table", description: "Reusable table", icon: "table" }];
          return micTypesCache;
        });
    }

    function openMicPicker() {
      if (!active || active.singleLine || mode === "html" || !active.mics || active.mics.length === 0) {
        return;
      }
      var picker = ensureMicPicker();
      picker.hidden = false;
      picker.innerHTML = "<p class=\"myron-text myron-text--muted\">Loading...</p>";
      loadMicTypes().then(function renderTypes(types) {
        picker.innerHTML = "";
        var allowed = {};
        active.mics.forEach(function mark(slug) { allowed[slug] = true; });
        var list = global.document.createElement("div");
        list.className = "mc-richtext-toolbar__mic-picker-types";
        types.filter(function filterType(type) { return allowed[type.slug]; }).forEach(function appendType(type) {
          var button = global.document.createElement("button");
          button.type = "button";
          button.className = "sg-button sg-button--secondary";
          button.textContent = type.label || type.slug;
          button.addEventListener("click", function onTypeClick(event) {
            event.preventDefault();
            openMicBankPicker(type.slug);
          });
          list.appendChild(button);
        });
        picker.appendChild(list);
      });
    }

    function micBankConfig(type) {
      if (type === "table") {
        return {
          endpoint: "/admin/api/v1/content/tables?limit=50",
          resultKey: "tables",
          tokenPrefix: "table",
          searchPlaceholder: "Search tables",
          emptyMessage: "No reusable tables yet.",
          label: function tableLabel(table) { return table.name || table.id; },
          searchText: function tableSearch(table) { return [table.name, table.caption, table.id].join(" "); }
        };
      }
      if (type === "form") {
        return {
          endpoint: "/admin/api/v1/content/forms?limit=50",
          resultKey: "forms",
          tokenPrefix: "form",
          searchPlaceholder: "Search forms",
          emptyMessage: "No reusable forms yet.",
          label: function formLabel(form) { return form.name || form.id; },
          searchText: function formSearch(form) { return [form.name, form.description, form.id].join(" "); }
        };
      }
      return null;
    }

    function openMicBankPicker(type) {
      var picker = ensureMicPicker();
      var config = micBankConfig(type);
      picker.innerHTML = "<p class=\"myron-text myron-text--muted\">Loading...</p>";
      if (!config) {
        picker.textContent = "No picker available for this type.";
        return;
      }
      fetch(config.endpoint, { credentials: "same-origin" })
        .then(function parse(response) { return response.json(); })
        .then(function render(payload) {
          var records = (payload && payload.result && payload.result[config.resultKey]) || [];
          picker.innerHTML = "";
          var search = global.document.createElement("input");
          search.className = "sg-field__control";
          search.placeholder = config.searchPlaceholder;
          var list = global.document.createElement("div");
          list.className = "mc-richtext-toolbar__mic-picker-list";
          function renderList() {
            var q = search.value.toLowerCase();
            list.innerHTML = "";
            var matched = records.filter(function filterRecord(record) {
              return !q || String(config.searchText(record) || "").toLowerCase().indexOf(q) !== -1;
            });
            if (!matched.length) {
              var empty = global.document.createElement("p");
              empty.className = "myron-text myron-text--muted";
              empty.textContent = records.length ? "No matches." : config.emptyMessage;
              list.appendChild(empty);
              return;
            }
            matched.forEach(function appendRecord(record) {
              var button = global.document.createElement("button");
              button.type = "button";
              button.className = "sg-button sg-button--secondary";
              button.textContent = config.label(record);
              button.addEventListener("click", function onPick(event) {
                event.preventDefault();
                insertTextAtCursor("[mic-" + config.tokenPrefix + "-" + record.id + "]");
                picker.hidden = true;
                active.surface.focus();
              });
              list.appendChild(button);
            });
          }
          search.addEventListener("input", renderList);
          picker.appendChild(search);
          picker.appendChild(list);
          renderList();
        });
    }

    function renderToolbar() {
      toolbarSlot.innerHTML = "";
      var group = null;
      commands.forEach(function appendCommand(definition) {
        if (!group || group.getAttribute("data-group") !== definition[3]) {
          group = global.document.createElement("div");
          group.className = "mc-richtext-toolbar__group";
          group.setAttribute("data-group", definition[3]);
          toolbarSlot.appendChild(group);
        }
        var button = global.document.createElement("button");
        button.type = "button";
        button.className = "mc-richtext-toolbar__button";
        button.innerHTML = commandIcon(definition[5], definition[2]);
        button.title = definition[1];
        button.setAttribute("aria-label", definition[1]);
        if (definition[4]) {
          button.setAttribute("data-mc-richtext-block", "true");
        }
        button.addEventListener("mousedown", function onCommandMousedown(event) {
          event.preventDefault();
        });
        button.addEventListener("click", function onCommandClick(event) {
          event.preventDefault();
          runCommand(definition[0]);
        });
        group.appendChild(button);
      });

      var tableGroup = global.document.createElement("div");
      tableGroup.className = "mc-richtext-toolbar__group mc-richtext-toolbar__table-tools";
      tableGroup.setAttribute("role", "group");
      tableGroup.setAttribute("aria-label", "Table editing");
      tableGroup.setAttribute("data-mc-richtext-table-tools", "true");
      tableGroup.hidden = true;
      tableCommands.forEach(function appendTableCommand(definition) {
        var button = global.document.createElement("button");
        button.type = "button";
        button.className = "mc-richtext-toolbar__button";
        button.innerHTML = commandIcon(definition[3], definition[2]);
        button.title = definition[1];
        button.setAttribute("aria-label", definition[1]);
        button.setAttribute("data-mc-richtext-table-button", "true");
        button.addEventListener("mousedown", function onTableCommandMousedown(event) {
          event.preventDefault();
        });
        button.addEventListener("click", function onTableCommandClick(event) {
          event.preventDefault();
          runCommand(definition[0]);
        });
        tableGroup.appendChild(button);
      });
      toolbarSlot.appendChild(tableGroup);

      var modeGroup = global.document.createElement("div");
      modeGroup.className = "mc-richtext-toolbar__group mc-richtext-toolbar__mode-toggle";
      modeGroup.setAttribute("role", "group");
      modeGroup.setAttribute("aria-label", "Rich text editor mode");
      ["visual", "html"].forEach(function appendMode(modeName) {
        var button = global.document.createElement("button");
        button.type = "button";
        button.className = "mc-richtext-toolbar__button mc-richtext-toolbar__mode-button";
        button.textContent = modeName === "visual" ? "Visual" : "HTML";
        button.title = modeName === "visual" ? "Visual mode" : "HTML mode";
        button.setAttribute("aria-label", button.title);
        button.setAttribute("data-mc-richtext-mode", modeName);
        button.addEventListener("mousedown", function onModeMousedown(event) {
          event.preventDefault();
        });
        button.addEventListener("click", function onModeClick(event) {
          event.preventDefault();
          updateMode(modeName);
        });
        modeGroup.appendChild(button);
      });
      toolbarSlot.appendChild(modeGroup);
      var micGroup = global.document.createElement("div");
      micGroup.className = "mc-richtext-toolbar__group";
      var micButton = global.document.createElement("button");
      micButton.type = "button";
      micButton.className = "mc-richtext-toolbar__button";
      micButton.innerHTML = commandIcon("mic", "Mic");
      micButton.title = "Insert mic";
      micButton.setAttribute("aria-label", "Insert mic");
      micButton.setAttribute("data-mc-richtext-mic-button", "true");
      micButton.addEventListener("mousedown", function onMicMousedown(event) {
        event.preventDefault();
      });
      micButton.addEventListener("click", function onMicClick(event) {
        event.preventDefault();
        openMicPicker();
      });
      micGroup.appendChild(micButton);
      toolbarSlot.appendChild(micGroup);
      toolbarSlot.classList.add("mc-richtext-toolbar");
      updateMode("visual");
      updateButtons();
    }

    renderToolbar();

    return {
      destroy: function destroy() {
        while (disposers.length) {
          disposers.pop()();
        }
        toolbarSlot.innerHTML = "";
        toolbarSlot.classList.remove("mc-richtext-toolbar");
      }
    };
  }

  global.setupRichtextToolbar = setupRichtextToolbar;
})(window);
