Plugin Directory

Changeset 2835882


Ignore:
Timestamp:
12/19/2022 08:31:51 AM (3 years ago)
Author:
magicroundabout
Message:

Update to version 1.12.0 from GitHub

Location:
turbo-admin
Files:
44 added
8 deleted
17 edited
1 copied

Legend:

Unmodified
Added
Removed
  • turbo-admin/assets/icon.svg

    • Property svn:mime-type set to image/svg+xml
  • turbo-admin/tags/1.12.0/dist/main.min.js

    r2703739 r2835882  
    808808  var import_fuse_6_4_6 = __toModule(require_fuse_6_4_6());
    809809
    810   // src/class-turbo-admin-menu-item.js
     810  // src/types/class-turbo-admin-menu-item.js
    811811  var TurboAdminMenuItem = class {
     812    title = "";
     813    action = "";
     814    parentTitle = "";
     815    noCache = false;
    812816    constructor(title, action, parentTitle, noCache = false) {
    813817      this.title = title;
     
    862866  var class_storage_default = Storage;
    863867
    864   // src/class-content-api.js
     868  // src/apis/class-content-api.js
    865869  var ContentApi = class {
    866870    constructor() {
    867871      this.active = false;
    868872      this.store = new class_storage_default();
     873      this.postTypes = [];
    869874      this.cache = {};
    870875    }
    871876    async discoverApiRoot() {
     877      console.log("Discovering API root");
    872878      let wpApiSettings = null;
    873879      this.storageKey = "wpApiSettings." + globalThis.taWp.home;
     
    902908        return;
    903909      }
     910      console.log("API Route Discovery failed");
     911    }
     912    async discoverPostTypes() {
     913      console.log("Discovering post types");
     914      if (!this.active) {
     915        console.log("Not active");
     916        this.postTypes = [];
     917        return;
     918      }
     919      this.postTypes = await this.getPostTypes();
     920      console.log("Discovered post types: ", this.postTypes);
    904921    }
    905922    userLoggedIn() {
     
    934951      }
    935952    }
    936     types() {
    937       return globalThis.turboAdmin.turboAdminPalette.postTypes;
    938     }
    939     async getPosts(searchString) {
    940       if (this.cache[searchString] !== void 0) {
    941         return this.cache[searchString];
     953    async getPostTypes() {
     954      if (this.cache["postsTypes"] !== void 0) {
     955        return this.cache["postTypes"];
     956      }
     957      const response = await this.get("types");
     958      const result = await response.json();
     959      this.cache["postTypes"] = result;
     960      return result;
     961    }
     962    async getPosts(searchString, postType = "any") {
     963      const cacheKey = `posts-${postType}-${searchString}`;
     964      if (this.cache[cacheKey] !== void 0) {
     965        return this.cache[cacheKey];
    942966      }
    943967      const response = await this.get("search", {
     
    945969        per_page: 100,
    946970        type: "post",
    947         subtype: "any"
     971        subtype: postType
    948972      });
    949973      const result = await response.json();
    950       this.cache[searchString] = result;
     974      this.cache[cacheKey] = result;
     975      return result;
     976    }
     977    async doesPostExist(postId) {
     978      if (this.cache["post-" + postId] !== void 0) {
     979        return this.cache["post-" + postId];
     980      }
     981      const init = {
     982        method: "GET",
     983        headers: {},
     984        mode: "cors",
     985        cache: "no-store",
     986        credentials: "include"
     987      };
     988      const response = await fetch(`${globalThis.taWp.siteUrl}/post.php?post=${postId}&action=edit`, init);
     989      this.cache["post-" + postId] = response;
     990      return response?.status === 200;
     991    }
     992    async getPlugins(searchString) {
     993      if (this.cache["plugins-" + searchString] !== void 0) {
     994        return this.cache["plugins-" + searchString];
     995      }
     996      let requestOptions = {};
     997      if (searchString) {
     998        requestOptions.search = searchString;
     999      }
     1000      const response = await this.get("plugins", requestOptions);
     1001      const result = await response.json();
     1002      this.cache["plugins-" + searchString] = result;
     1003      return result;
     1004    }
     1005    async getUsers(searchString) {
     1006      if (this.cache["users-" + searchString] !== void 0) {
     1007        return this.cache["users-" + searchString];
     1008      }
     1009      const response = await this.get("users", {
     1010        search: searchString,
     1011        per_page: 100,
     1012        context: "edit"
     1013      });
     1014      const result = await response.json();
     1015      this.cache["users-" + searchString] = result;
    9511016      return result;
    9521017    }
     
    9561021        headers: {},
    9571022        mode: "cors",
    958         cache: "no-store"
     1023        cache: "no-store",
     1024        credentials: "include"
    9591025      };
    9601026      if (this.apiNonce) {
     
    9621028      }
    9631029      const params = this.makeParamString(data);
    964       const response = await fetch(`${this.apiBase}${path}/?${params}`);
     1030      const response = await fetch(`${this.apiBase}${path}/?${params}`, init);
     1031      if (response.status < 200 || response.status >= 300) {
     1032        globalThis.turboAdmin.turboAdminPalette.showPaletteNotice("WordPress API Error. Try visiting the dashboard to refresh things.");
     1033      }
    9651034      return response;
    9661035    }
    9671036  };
    9681037  var class_content_api_default = ContentApi;
     1038
     1039  // src/types/class-submenu-item.js
     1040  var SubmenuItem = class {
     1041    title;
     1042    url;
     1043    attributes = [];
     1044    constructor(title, url) {
     1045      this.title = title;
     1046      this.url = url;
     1047    }
     1048    addAttribute(name, value) {
     1049      this.attributes.push({
     1050        name,
     1051        value
     1052      });
     1053    }
     1054  };
     1055  var class_submenu_item_default = SubmenuItem;
     1056
     1057  // src/types/class-content-item.js
     1058  var ContentItem = class {
     1059    title = "";
     1060    subtype = "";
     1061    url = "";
     1062    submenuItems = [];
     1063  };
     1064  var class_content_item_default = ContentItem;
     1065
     1066  // src/types/class-search-mode.js
     1067  var SearchMode = class {
     1068    keyword = "";
     1069    displayName = "";
     1070    searchCallback;
     1071    defaultItemsCallback = null;
     1072    constructor(keyword, displayName, searchCallback, defaultItemsCallback = null) {
     1073      this.keyword = keyword;
     1074      this.displayName = displayName;
     1075      this.searchCallback = searchCallback;
     1076      this.defaultItemsCallback = defaultItemsCallback;
     1077    }
     1078  };
     1079  var class_search_mode_default = SearchMode;
    9691080
    9701081  // src/class-turbo-admin-palette.js
     
    9761087      this.paletteInnerElement = document.getElementById("ta-command-palette");
    9771088      this.paletteInputElement = document.getElementById("ta-command-palette-input");
     1089      this.paletteItemsContainerElement = document.getElementById("ta-command-palette-items-container");
    9781090      this.paletteItemsElement = document.getElementById("ta-command-palette-items");
     1091      this.paletteSubmenuContainerElement = document.getElementById("ta-command-palette-submenu-container");
     1092      this.paletteSearchModeTag = document.getElementById("ta-command-palette-search-mode-tag");
     1093      this.paletteSearchModeTabNotice = document.getElementById("ta-command-palette-tab-notice");
     1094      this.paletteSearchModeTabNoticeText = document.getElementById("ta-command-palette-tab-notice-text");
     1095      this.paletteNoticeElement = document.getElementById("ta-command-palette-notice");
     1096      if (globalThis.turboAdmin.menuNeedsRefresh) {
     1097        this.showPaletteNotice("Menu needs refreshing. Visit the Dashboard to refresh.");
     1098      }
     1099      this.profileLinkElem = document.getElementById("wp-admin-bar-edit-profile");
     1100      this.profileLink = null;
     1101      if (this.profileLinkElem) {
     1102        this.profileLink = this.profileLinkElem.querySelector("a").href;
     1103      }
    9791104      this.paletteData = paletteData;
    980       this.postTypes = [];
    981       this.fetchPostTypes();
     1105      this.paletteDataBackup = null;
     1106      this.paletteItemsBackup = null;
     1107      this.paletteItemIndexBackup = null;
     1108      this.searchMode = null;
    9821109      this.paletteItems = [];
    9831110      this.itemIndex = {};
     
    10171144      return this.isMac() ? e.metaKey : e.ctrlKey;
    10181145    }
    1019     fetchPostTypes() {
    1020       if (!globalThis.contentApi.active) {
    1021         this.postTypes = [];
    1022         return;
    1023       }
    1024       globalThis.contentApi.get("types").then((response) => {
    1025         response.json().then((types) => {
    1026           this.postTypes = types;
    1027         });
    1028       });
     1146    inSearchMode() {
     1147      return this.searchMode !== null;
    10291148    }
    10301149    buildPaletteItems() {
     
    10541173      return Boolean(this.itemIndex[url]);
    10551174    }
    1056     injectContentItems(contentItems) {
     1175    setContentItems(contentItems) {
     1176      this.paletteItems = [];
     1177      this.itemIndex = [];
     1178      this.injectContentItems(contentItems, false);
     1179    }
     1180    injectContentItems(contentItems, andRunSearch = true) {
    10571181      console.log("Injecting items");
    1058       const profileLinkElem = document.getElementById("wp-admin-bar-edit-profile");
    1059       let profileLink = null;
    1060       if (profileLinkElem) {
    1061         profileLink = profileLinkElem.querySelector("a").href;
    1062       }
    1063       let oxygenLinkElem = document.getElementById("toplevel_page_ct_dashboard_page");
    1064       if (!oxygenLinkElem) {
    1065         oxygenLinkElem = document.getElementById("wp-admin-bar-oxygen_admin_bar_menu");
    1066       }
    1067       if (!oxygenLinkElem) {
    1068         oxygenLinkElem = Number(window.localStorage.getItem("ta-has-oxygen-builder"));
    1069       }
    1070       window.localStorage.setItem("ta-has-oxygen-builder", Boolean(oxygenLinkElem) ? "1" : "0");
    10711182      if (contentItems.length > 0) {
    1072         contentItems.forEach((item) => {
    1073           const itemTitle = item.title;
    1074           const itemType = item.subtype;
    1075           const itemUrl = item.url;
    1076           if (this.contentItemExists(itemUrl)) {
    1077             console.log("Not adding duplicate");
    1078             return;
     1183        contentItems.forEach(this.injectItem.bind(this));
     1184      }
     1185      if (andRunSearch) {
     1186        this.paletteFuse = new import_fuse_6_4_6.default(this.paletteItems, this.paletteFuseOptions);
     1187        this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map((i) => i.item);
     1188      }
     1189      this.updatePaletteItems();
     1190    }
     1191    injectItem(item) {
     1192      const itemTitle = item.title;
     1193      const itemType = item.subtype;
     1194      const itemUrl = item.url;
     1195      if (this.contentItemExists(itemUrl)) {
     1196        console.log("Not adding duplicate");
     1197        return;
     1198      }
     1199      let title = itemTitle;
     1200      if (itemType) {
     1201        const itemTypeName = globalThis.contentApi.postTypes[itemType] ? globalThis.contentApi.postTypes[itemType].name : itemType;
     1202        title += ` (${itemTypeName})`;
     1203      }
     1204      const li = document.createElement("li");
     1205      const a = document.createElement("a");
     1206      let subMenu = null;
     1207      if (item.submenuItems.length > 0) {
     1208        subMenu = document.createElement("div");
     1209        const subMenuTitle = document.createElement("div");
     1210        const subMenuItems = document.createElement("ul");
     1211        subMenu.classList.add("ta-submenu");
     1212        subMenuTitle.classList.add("ta-submenu-title");
     1213        subMenuTitle.textContent = this.htmlDecode(itemTitle);
     1214        subMenuItems.classList.add("ta-submenu-items");
     1215        subMenu.appendChild(subMenuTitle);
     1216        for (let i = 0; i < item.submenuItems.length; i++) {
     1217          const subMenuItem = item.submenuItems[i];
     1218          const subMenuListItem = document.createElement("li");
     1219          const subMenuLink = document.createElement("a");
     1220          subMenuLink.innerText = subMenuItem.title;
     1221          subMenuLink.href = subMenuItem.url;
     1222          for (let a2 = 0; a2 < subMenuItem.attributes.length; a2++) {
     1223            subMenuLink.setAttribute(subMenuItem.attributes[a2].name, subMenuItem.attributes[a2].value);
    10791224          }
    1080           const itemTypeName = this.postTypes[itemType] ? this.postTypes[itemType].name : itemType;
    1081           const title = `${itemTitle} (${itemTypeName})`;
    1082           const li = document.createElement("li");
    1083           const a = document.createElement("a");
    1084           const subMenu = document.createElement("div");
    1085           const subMenuTitle = document.createElement("div");
    1086           const subMenuItems = document.createElement("ul");
    1087           subMenu.classList.add("ta-submenu");
    1088           subMenuTitle.classList.add("ta-submenu-title");
    1089           subMenuTitle.textContent = this.htmlDecode(itemTitle);
    1090           subMenuItems.classList.add("ta-submenu-items");
    1091           subMenu.appendChild(subMenuTitle);
    1092           subMenu.appendChild(subMenuItems);
    1093           const subMenuItem1 = document.createElement("li");
    1094           const subMenuLink1 = document.createElement("a");
    1095           subMenuLink1.innerText = "View";
    1096           subMenuLink1.href = itemUrl;
    1097           subMenuItem1.appendChild(subMenuLink1);
    1098           subMenuItems.appendChild(subMenuItem1);
    1099           if (profileLink) {
    1100             const editLink = profileLink.replace("profile.php", `post.php?post=${item.id}&action=edit`);
    1101             const subMenuItem2 = document.createElement("li");
    1102             const subMenuLink2 = document.createElement("a");
    1103             subMenuLink2.innerText = "Edit";
    1104             subMenuLink2.href = editLink;
    1105             subMenuItem2.appendChild(subMenuLink2);
    1106             subMenuItems.appendChild(subMenuItem2);
    1107           }
    1108           if (oxygenLinkElem) {
    1109             const oxygenLink = globalThis.taWp.home + `?page_id=${item.id}&ct_builder=true&ct_inner=true`;
    1110             const subMenuItem32 = document.createElement("li");
    1111             const subMenuLink32 = document.createElement("a");
    1112             subMenuLink32.innerText = "Edit with Oxygen";
    1113             subMenuLink32.href = oxygenLink;
    1114             subMenuItem32.appendChild(subMenuLink32);
    1115             subMenuItems.appendChild(subMenuItem32);
    1116           }
    1117           const subMenuItem3 = document.createElement("li");
    1118           const subMenuLink3 = document.createElement("a");
    1119           subMenuLink3.innerText = "Copy link";
    1120           subMenuLink3.href = itemUrl;
    1121           subMenuLink3.setAttribute("data-action", "clipboard");
    1122           subMenuItem3.appendChild(subMenuLink3);
    1123           subMenuItems.appendChild(subMenuItem3);
    1124           li.classList.add("ta-has-child-menu");
    1125           li.appendChild(a);
    1126           li.appendChild(subMenu);
    1127           a.href = itemUrl;
    1128           a.innerHTML = title;
    1129           this.addPaletteListItem(li);
    1130         });
    1131       }
    1132       this.paletteFuse = new import_fuse_6_4_6.default(this.paletteItems, this.paletteFuseOptions);
    1133       this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map((i) => i.item);
    1134       this.updatePaletteItems();
     1225          subMenuListItem.appendChild(subMenuLink);
     1226          subMenuItems.appendChild(subMenuListItem);
     1227        }
     1228        subMenu.appendChild(subMenuItems);
     1229        li.classList.add("ta-has-child-menu");
     1230      }
     1231      a.href = itemUrl;
     1232      a.innerHTML = title;
     1233      li.appendChild(a);
     1234      if (subMenu !== null) {
     1235        li.appendChild(subMenu);
     1236      }
     1237      this.addPaletteListItem(li);
    11351238    }
    11361239    async handleGlobalKey(e) {
     
    11431246          this.showPalette();
    11441247        }
     1248        return;
    11451249      }
    11461250      if (e.code === "Escape" && this.paletteShown()) {
    11471251        if (this.isSubMenuOpen()) {
    11481252          this.closeSubMenu();
     1253        } else if (this.inSearchMode()) {
     1254          this.leaveSearchMode();
    11491255        } else {
    11501256          this.hidePalette();
    11511257        }
     1258        return;
    11521259      }
    11531260      if (this.paletteShown()) {
     
    11641271      return keysPressed;
    11651272    }
     1273    maybeHighlightInputKeyword(newKey) {
     1274      if (this.inSearchMode()) {
     1275        return;
     1276      }
     1277      let newInputValue = this.paletteInputElement.value;
     1278      if (newKey.length === 1) {
     1279        newInputValue += newKey;
     1280      }
     1281      if (newKey === "Backspace") {
     1282        newInputValue = newInputValue.slice(0, -1);
     1283      }
     1284      if (this.isKeyword(newInputValue)) {
     1285        this.paletteSearchModeTabNoticeText.innerText = `Search for ${newInputValue}`;
     1286        this.paletteSearchModeTabNotice.classList.add("active");
     1287      } else {
     1288        this.unhighlightInputKeyword();
     1289      }
     1290    }
     1291    unhighlightInputKeyword() {
     1292      this.paletteSearchModeTabNotice.classList.remove("active");
     1293    }
    11661294    async debouncedPaletteSearchAndUpdate() {
    1167       if (this.paletteInputElement.value !== "" && this.paletteInputElement.value.length <= 2 || this.postTypes === []) {
     1295      if (!this.inSearchMode()) {
    11681296        this.debounceTimeout = null;
    11691297        await this.paletteSearchAndUpdate();
    11701298        return;
    11711299      }
    1172       if (!this.debounceTimeout) {
    1173         this.debounceTimeout = setTimeout(async function() {
    1174           this.debounceTimeout = null;
    1175           await this.paletteSearchAndUpdate();
    1176         }.bind(this), 750);
    1177       }
     1300      clearTimeout(this.debounceTimeout);
     1301      this.debounceTimeout = setTimeout(async function() {
     1302        this.debounceTimeout = null;
     1303        await this.paletteSearchAndUpdate();
     1304      }.bind(this), 750);
     1305    }
     1306    isKeyword(inputString) {
     1307      return Object.keys(globalThis.turboAdmin.searchModes).includes(inputString);
     1308    }
     1309    showPaletteNotice(text) {
     1310      this.paletteNoticeElement.classList.add("active");
     1311      this.paletteNoticeElement.innerText = text;
     1312    }
     1313    hidePaletteNotice() {
     1314      this.paletteNoticeElement.classList.remove("active");
    11781315    }
    11791316    async paletteActions(e) {
     
    11891326      }
    11901327      if (e.code === "Enter" && this.paletteShown()) {
     1328        e.preventDefault();
    11911329        this.doAction(this.metaPressed(e));
    11921330        return;
     
    11951333        return;
    11961334      }
     1335      this.maybeHighlightInputKeyword(e.key);
     1336      if (!this.inSearchMode() && (e.code === "Tab" || e.key === ":")) {
     1337        console.log("Checking for search mode");
     1338        let inputValue = this.paletteInputElement.value;
     1339        if (this.isKeyword(inputValue)) {
     1340          console.log("Found search mode " + inputValue);
     1341          e.preventDefault();
     1342          await this.enterSearchMode(globalThis.turboAdmin.searchModes[inputValue]);
     1343          return;
     1344        }
     1345      }
     1346      if (this.inSearchMode() && e.code === "Backspace" && this.paletteInputElement.value === "") {
     1347        e.preventDefault();
     1348        this.leaveSearchMode();
     1349        return;
     1350      }
    11971351      await this.debouncedPaletteSearchAndUpdate();
    11981352    }
     1353    async enterSearchMode(searchMode) {
     1354      console.log("Entering search mode for keyword " + searchMode.keyword);
     1355      this.backupPaletteData();
     1356      this.paletteData = [];
     1357      this.paletteItems = [];
     1358      this.itemIndex = [];
     1359      this.hidePaletteNotice();
     1360      this.searchMode = searchMode;
     1361      this.paletteInputElement.value = "";
     1362      this.addSearchModeTag(searchMode.displayName);
     1363      this.unhighlightInputKeyword();
     1364      this.updatePaletteItems();
     1365      if (searchMode.defaultItemsCallback !== null) {
     1366        this.paletteInnerElement.classList.add("loading");
     1367        const results = await searchMode.defaultItemsCallback();
     1368        this.setContentItems(results);
     1369        this.paletteInnerElement.classList.remove("loading");
     1370      }
     1371    }
     1372    leaveSearchMode() {
     1373      const searchMode = this.searchMode;
     1374      this.searchMode = null;
     1375      this.removeSearchModeTag();
     1376      this.restorePaletteData();
     1377      this.paletteInputElement.value = searchMode.keyword;
     1378      this.maybeHighlightInputKeyword("");
     1379      this.paletteSearchAndUpdate();
     1380    }
     1381    backupPaletteData() {
     1382      this.paletteDataBackup = this.paletteData;
     1383      this.paletteItemsBackup = this.paletteItems;
     1384      this.paletteItemIndexBackup = this.itemIndex;
     1385    }
     1386    restorePaletteData() {
     1387      this.paletteData = this.paletteDataBackup;
     1388      this.paletteItems = this.paletteItemsBackup;
     1389      this.itemIndex = this.paletteItemIndexBackup;
     1390    }
     1391    addSearchModeTag(title) {
     1392      this.paletteSearchModeTag.classList.add("active");
     1393      this.paletteSearchModeTag.innerText = title;
     1394    }
     1395    removeSearchModeTag() {
     1396      this.paletteSearchModeTag.classList.remove("active");
     1397    }
     1398    isPaletteOpen() {
     1399      return this.paletteElement?.classList.contains("active");
     1400    }
    11991401    showPalette() {
     1402      if (this.isPaletteOpen()) {
     1403        return;
     1404      }
    12001405      this.paletteInputElement.value = "";
    1201       this.paletteItemsElement.scrollTop = 0;
     1406      this.paletteInputElement?.focus();
    12021407      this.paletteElement?.classList.add("active");
    1203       this.paletteInputElement?.focus();
     1408      setTimeout(() => this.paletteItemsElement.scrollTop = 0, 100);
    12041409    }
    12051410    hidePalette() {
     
    12111416        this.closeSubMenu();
    12121417      }
     1418      if (this.searchMode !== null) {
     1419        this.leaveSearchMode();
     1420      }
    12131421    }
    12141422    paletteShown() {
     
    12341442    setSelectedElement() {
    12351443      if (this.isSubMenuOpen()) {
    1236         this.paletteItemsElement?.querySelectorAll(".ta-submenu.active li.selected")?.forEach((e) => e.classList.remove("selected"));
     1444        this.paletteSubmenuContainerElement?.querySelectorAll(".ta-submenu li.selected")?.forEach((e) => e.classList.remove("selected"));
    12371445        this.selectedSubItem.classList.add("selected");
    12381446      } else {
     
    13011509    }
    13021510    openSubMenu(subMenuElement) {
    1303       const subMenuHeight = subMenuElement.offsetHeight;
    1304       this.paletteItemsElement.style.minHeight = subMenuHeight + "px";
    1305       subMenuElement.classList.add("active");
     1511      this.paletteSubmenuContainerElement.replaceChildren(subMenuElement);
     1512      const subMenuHeight = this.paletteSubmenuContainerElement.offsetHeight;
     1513      this.paletteItemsContainerElement.style.minHeight = subMenuHeight + "px";
     1514      this.paletteSubmenuContainerElement.classList.add("active");
    13061515      this.selectedSubItem = subMenuElement.querySelector("li");
    13071516      this.openedSubMenu = subMenuElement;
     
    13141523        subMenuElement = document.querySelector(".ta-submenu.active");
    13151524      }
    1316       subMenuElement.classList.remove("active");
     1525      this.paletteSubmenuContainerElement.classList.remove("active");
    13171526      this.selectedSubItem.classList.remove("active");
    1318       this.paletteItemsElement.style.minHeight = "auto";
     1527      this.paletteItemsContainerElement.style.minHeight = "auto";
    13191528      this.selectedSubItem = null;
    13201529      this.openedSubMenu = null;
     
    13381547      const link = item.querySelector("a");
    13391548      const url = link.href;
     1549      if (link.getAttribute("href") === "") {
     1550        return;
     1551      }
    13401552      if (link.dataset.action === "clipboard") {
    13411553        navigator.clipboard.writeText(url);
     
    13561568    }
    13571569    async paletteSearch() {
    1358       this.buildPaletteItems();
    1359       if (this.paletteInputElement.value !== "") {
    1360         this.paletteFuse = new import_fuse_6_4_6.default(this.paletteItems, this.paletteFuseOptions);
    1361         this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map((i) => i.item);
    1362       }
    1363       if (globalThis.contentApi.active && this.postTypes !== [] && this.paletteInputElement.value.length > 2) {
     1570      if (!this.searchMode) {
     1571        this.buildPaletteItems();
     1572        if (this.paletteInputElement.value !== "") {
     1573          this.paletteFuse = new import_fuse_6_4_6.default(this.paletteItems, this.paletteFuseOptions);
     1574          this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map((i) => i.item);
     1575        }
     1576        return;
     1577      }
     1578      if (this.paletteInputElement.value.length === 0) {
    13641579        this.paletteInnerElement.classList.add("loading");
    1365         globalThis.contentApi.getPosts(this.paletteInputElement.value).then((results) => {
    1366           this.injectContentItems(results);
    1367           this.paletteInnerElement.classList.remove("loading");
    1368         });
     1580        let results = [];
     1581        if (this.searchMode.defaultItemsCallback !== null) {
     1582          results = await this.searchMode.defaultItemsCallback();
     1583        }
     1584        this.setContentItems(results);
     1585        this.paletteInnerElement.classList.remove("loading");
     1586      } else {
     1587        this.paletteInnerElement.classList.add("loading");
     1588        const results = await this.searchMode.searchCallback(this.paletteInputElement.value);
     1589        this.setContentItems(results);
     1590        this.paletteInnerElement.classList.remove("loading");
    13691591      }
    13701592    }
     
    13841606  var class_turbo_admin_palette_default = TurboAdminPalette;
    13851607
    1386   // src/class-turbo-admin-wp-block-editor-fullscreen-kill.js
    1387   var TurboAdminWpBlockEditorFullscreenKill = class {
    1388     constructor() {
    1389       const attrObserver = new MutationObserver((mutations) => {
    1390         mutations.forEach((mu) => {
    1391           if (mu.type !== "attributes" && mu.attributeName !== "class") {
    1392             return;
    1393           }
    1394           if (mu.target.classList.contains("is-fullscreen-mode")) {
    1395             this.killFullScreenEditor();
    1396           }
    1397         });
    1398       });
    1399       attrObserver.observe(document.body, {attributes: true});
    1400       this.killFullScreenEditor();
    1401     }
    1402     killFullScreenEditor() {
    1403       if (!document.body.classList.contains("is-fullscreen-mode")) {
    1404         return;
    1405       }
    1406       document.body.classList.remove("is-fullscreen-mode");
    1407       document.body.classList.add("turbo-admin-killed-fullscreen");
    1408       const newStyles = document.createElement("style");
    1409       newStyles.innerHTML = "body.turbo-admin-killed-fullscreen .edit-post-fullscreen-mode-close { display: none; }";
    1410       document.body.appendChild(newStyles);
    1411     }
     1608  // src/types/class-item-definition.js
     1609  var ItemDefinition = class {
     1610    detectType = "dom";
     1611    detectSelector = "";
     1612    detectSelectorNone = "";
     1613    itemTitleFunction = null;
     1614    itemUrlFunction = null;
     1615    noCache = false;
    14121616  };
    1413   var class_turbo_admin_wp_block_editor_fullscreen_kill_default = TurboAdminWpBlockEditorFullscreenKill;
     1617  var class_item_definition_default = ItemDefinition;
    14141618
    1415   // src/class-turbo-admin-wp-block-editor-welcome-guide-kill.js
    1416   var TurboAdminWpBlockEditorWelcomeGuideKill = class {
    1417     constructor() {
    1418       const attrObserver = new MutationObserver((mutations) => {
    1419         mutations.forEach((mu) => {
    1420           if (document.body.classList.contains("ta-killed-post-welcome-guide")) {
    1421             return;
    1422           }
    1423           if (mu.type !== "attributes" && mu.attributeName !== "class") {
    1424             return;
    1425           }
    1426           if (!mu.target.classList.contains("modal-open")) {
    1427             return;
    1428           }
    1429           const welcomeGuide = document.querySelector(".edit-post-welcome-guide");
    1430           if (welcomeGuide) {
    1431             this.killWelcomeGuide();
    1432           }
    1433         });
    1434       });
    1435       attrObserver.observe(document.body, {attributes: true});
    1436       this.killWelcomeGuide();
    1437     }
    1438     killWelcomeGuide() {
    1439       const welcomeGuide = document.querySelector(".edit-post-welcome-guide");
    1440       if (welcomeGuide) {
    1441         const closeButton = welcomeGuide.querySelector(".components-modal__header button");
    1442         if (closeButton) {
    1443           closeButton.click();
    1444           document.body.classList.add("ta-killed-post-welcome-guide");
    1445         }
    1446       }
     1619  // src/types/class-turbo-admin-plugin.js
     1620  var TurboAdminPlugin = class {
     1621    name = "";
     1622    searchModes = [];
     1623    activated = false;
     1624    constructor(pluginName) {
     1625      this.name = pluginName;
     1626      this.registerPlugin();
     1627    }
     1628    registerPlugin() {
     1629      console.log("Inside plugin - requested registration of " + this.name);
     1630      globalThis.turboAdmin.registerPlugin(this);
     1631    }
     1632    shouldActivate() {
     1633      return false;
     1634    }
     1635    activate() {
     1636      this.activated = true;
     1637      this.registerSearchModes();
     1638    }
     1639    registerSearchModes() {
     1640      this.searchModes.forEach(globalThis.turboAdmin.registerSearchMode);
     1641    }
     1642    getAdditionalItemDefinitions() {
     1643      return [];
     1644    }
     1645    saveSetting(key, value) {
    14471646    }
    14481647  };
    1449   var class_turbo_admin_wp_block_editor_welcome_guide_kill_default = TurboAdminWpBlockEditorWelcomeGuideKill;
     1648  var class_turbo_admin_plugin_default = TurboAdminPlugin;
    14501649
    14511650  // src/class-turbo-admin-wp-notices.js
     
    15471746      noticesPanelInner.id = "ta-notices-panel-inner";
    15481747      noticesToHide.forEach((notice) => {
    1549         notice.classList.add("inline");
    15501748        noticesPanelInner.append(notice);
    15511749      });
     
    17431941  var class_list_table_shortcuts_default = ListTableShortcuts;
    17441942
    1745   // src/class-turbo-admin-barkeeper.js
    1746   var TurboAdminBarkeeper = class {
    1747     constructor(barkeeperState) {
     1943  // src/plugins/class-turbo-admin-barkeeper.js
     1944  var TurboAdminBarkeeper = class extends class_turbo_admin_plugin_default {
     1945    constructor() {
     1946      super("Barkeeper");
     1947    }
     1948    shouldActivate() {
     1949      if (globalThis.turboAdmin.options["barkeeper"] !== true) {
     1950        return false;
     1951      }
    17481952      if (!document.getElementById("wpadminbar")) {
    1749         return;
    1750       }
     1953        return false;
     1954      }
     1955      return true;
     1956    }
     1957    activate() {
     1958      super.activate();
    17511959      this.exclusionIds = [
    17521960        "wp-admin-bar-menu-toggle",
     
    17551963        "wp-admin-bar-updates"
    17561964      ];
    1757       this.barkeeperState = barkeeperState;
     1965      this.barkeeperState = globalThis.turboAdmin.options["barkeeper-state"];
    17581966      this.root = document.getElementById("wp-admin-bar-root-default");
    17591967      this.itemsToHide = document.querySelectorAll("#wp-admin-bar-root-default > li");
     
    17731981        this.root.classList.toggle("ta-barkeeper-closed");
    17741982        this.barkeeperState = this.barkeeperState === "open" ? "closed" : "open";
    1775         if (typeof browser === "object") {
    1776           browser.runtime.sendMessage({
    1777             action: "barkeeperSetState",
    1778             barkeeperState: this.barkeeperState
    1779           });
    1780         } else {
    1781           window.localStorage.setItem("turboAdminBarkeeperState", this.barkeeperState);
    1782         }
     1983        browser.runtime.sendMessage({
     1984          action: "barkeeperSetState",
     1985          barkeeperState: this.barkeeperState
     1986        });
    17831987      });
    17841988      this.root.insertAdjacentElement("afterend", this.button);
     
    17861990  };
    17871991  var class_turbo_admin_barkeeper_default = TurboAdminBarkeeper;
     1992
     1993  // src/plugins/class-turbo-admin-content-search.js
     1994  var TurboAdminContentSearch = class extends class_turbo_admin_plugin_default {
     1995    constructor() {
     1996      super("WP Content");
     1997      const postTypeKeys = Object.keys(globalThis.contentApi.postTypes);
     1998      for (let i = 0; i < postTypeKeys.length; i++) {
     1999        const thisPostTypeKey = postTypeKeys[i];
     2000        const thisPostType = globalThis.contentApi.postTypes[thisPostTypeKey];
     2001        this.searchModes.push(this.makePostTypeSearchMode(thisPostType));
     2002      }
     2003      this.searchModes.push(new class_search_mode_default("id", "Post ID", this.postById.bind(this)));
     2004      this.searchModes.push(new class_search_mode_default("search", "All post types", this.contentSearch.bind(this)));
     2005      this.searchModes.push(new class_search_mode_default("find", "All post types", this.contentSearch.bind(this)));
     2006    }
     2007    shouldActivate() {
     2008      return true;
     2009    }
     2010    activate() {
     2011      super.activate();
     2012    }
     2013    makePostTypeSearchMode(postType) {
     2014      return new class_search_mode_default(postType.slug, postType.name, (searchString) => this.contentSearch(searchString, postType.slug));
     2015    }
     2016    async contentSearch(searchString, postType = "any") {
     2017      const results = await globalThis.contentApi.getPosts(searchString, postType);
     2018      if (!Array.isArray(results)) {
     2019        return [];
     2020      }
     2021      return results.map((result) => {
     2022        const item = new class_content_item_default();
     2023        item.title = result.title;
     2024        item.subtype = result.subtype;
     2025        item.url = result.url;
     2026        item.submenuItems = item.submenuItems.concat(this.makeSubmenuItems(result.id, item));
     2027        return item;
     2028      });
     2029    }
     2030    async postById(postId) {
     2031      if (!postId.trim().match(/^\d+$/)) {
     2032        return [];
     2033      }
     2034      const postExists = await globalThis.contentApi.doesPostExist(postId);
     2035      const resultAsContentItem = new class_content_item_default();
     2036      if (!postExists) {
     2037        resultAsContentItem.title = "Post does not exist or is not visible";
     2038        return [resultAsContentItem];
     2039      }
     2040      resultAsContentItem.title = `Post ID: ${postId}`;
     2041      resultAsContentItem.url = globalThis.taWp.home + `/?p=${postId}`;
     2042      resultAsContentItem.submenuItems = resultAsContentItem.submenuItems.concat(this.makeSubmenuItems(postId, resultAsContentItem));
     2043      return [resultAsContentItem];
     2044    }
     2045    makeSubmenuItems(postId, contentItem) {
     2046      const itemsToReturn = [];
     2047      itemsToReturn.push(new class_submenu_item_default("View", contentItem.url));
     2048      if (globalThis.turboAdmin.turboAdminPalette.profileLink) {
     2049        const editLink = globalThis.taWp.siteUrl + `/post.php?post=${postId}&action=edit`;
     2050        itemsToReturn.push(new class_submenu_item_default("Edit", editLink));
     2051        if (globalThis.turboAdmin.hasActivatedPlugin("OxygenBuilder")) {
     2052          const oxygenLink = globalThis.taWp.home + `?page_id=${postId}&ct_builder=true&ct_inner=true`;
     2053          itemsToReturn.push(new class_submenu_item_default("Edit with Oxygen", oxygenLink));
     2054        }
     2055      }
     2056      const copyLinkItem = new class_submenu_item_default("Copy link", contentItem.url);
     2057      copyLinkItem.addAttribute("data-action", "clipboard");
     2058      itemsToReturn.push(copyLinkItem);
     2059      return itemsToReturn;
     2060    }
     2061  };
     2062  var class_turbo_admin_content_search_default = TurboAdminContentSearch;
     2063
     2064  // src/plugins/class-turbo-admin-plugins.js
     2065  var TurboAdminPluginSearch = class extends class_turbo_admin_plugin_default {
     2066    constructor() {
     2067      super("WP Plugins");
     2068      this.searchModes.push(new class_search_mode_default("plugin", "Plugins", this.pluginSearch, this.defaultPluginItems.bind(this)));
     2069    }
     2070    shouldActivate() {
     2071      return true;
     2072    }
     2073    activate() {
     2074      super.activate();
     2075    }
     2076    async defaultPluginItems() {
     2077      return await this.pluginSearch("");
     2078    }
     2079    async pluginSearch(searchString) {
     2080      const results = await globalThis.contentApi.getPlugins(searchString);
     2081      if (!Array.isArray(results)) {
     2082        return [];
     2083      }
     2084      return results.map((result) => {
     2085        const item = new class_content_item_default();
     2086        item.title = result.name;
     2087        item.subtype = "Plugin";
     2088        const itemViewUrlParams = new URLSearchParams();
     2089        itemViewUrlParams.set("plugin_status", "all");
     2090        itemViewUrlParams.set("s", result.name);
     2091        item.submenuItems.push(new class_submenu_item_default("View", globalThis.taWp.siteUrl + "/plugins.php?" + itemViewUrlParams.toString()));
     2092        return item;
     2093      });
     2094    }
     2095  };
     2096  var class_turbo_admin_plugins_default = TurboAdminPluginSearch;
     2097
     2098  // src/plugins/class-turbo-admin-users.js
     2099  var TurboAdminUserSearch = class extends class_turbo_admin_plugin_default {
     2100    constructor() {
     2101      super("WP Users");
     2102      this.searchModes.push(new class_search_mode_default("user", "Users", this.userSearch, this.defaultUserItems.bind(this)));
     2103    }
     2104    shouldActivate() {
     2105      return true;
     2106    }
     2107    activate() {
     2108      super.activate();
     2109    }
     2110    async defaultUserItems() {
     2111      return await this.userSearch("");
     2112    }
     2113    async userSearch(searchString) {
     2114      const results = await globalThis.contentApi.getUsers(searchString);
     2115      if (!Array.isArray(results)) {
     2116        return [];
     2117      }
     2118      return results.map((result) => {
     2119        const item = new class_content_item_default();
     2120        if (result.first_name && result.last_name) {
     2121          item.title = `${result.first_name} ${result.last_name} - `;
     2122        }
     2123        item.title += result.email;
     2124        item.subtype = result.roles[0];
     2125        item.url = globalThis.taWp.siteUrl + `/user-edit.php?user_id=${result.id}`;
     2126        return item;
     2127      });
     2128    }
     2129  };
     2130  var class_turbo_admin_users_default = TurboAdminUserSearch;
     2131
     2132  // src/plugins/class-turbo-admin-mu-sites.js
     2133  var TurboAdminMUSites = class extends class_turbo_admin_plugin_default {
     2134    constructor() {
     2135      super("WP Multisite Sites");
     2136      this.searchModes.push(new class_search_mode_default("site", "Sites", this.siteSearch.bind(this), this.defaultSiteItems.bind(this)));
     2137    }
     2138    shouldActivate() {
     2139      return Boolean(document.querySelector("#wp-admin-bar-my-sites"));
     2140    }
     2141    activate() {
     2142      super.activate();
     2143    }
     2144    async defaultSiteItems() {
     2145      return await this.siteSearch("");
     2146    }
     2147    async siteSearch(searchString) {
     2148      const sites = document.querySelectorAll("#wp-admin-bar-my-sites #wp-admin-bar-my-sites-list > li");
     2149      if (sites.length === 0) {
     2150        return [];
     2151      }
     2152      const sitesArray = Array.from(sites);
     2153      const sitesLinks = sitesArray.map((site) => site.querySelector("a"));
     2154      const filteredSites = sitesLinks.filter((site) => site.innerText.toLowerCase().includes(searchString.toLowerCase()));
     2155      return filteredSites.map((site) => {
     2156        const item = new class_content_item_default();
     2157        item.title = site.innerText;
     2158        item.subtype = "Site";
     2159        item.url = site.href;
     2160        item.submenuItems = item.submenuItems.concat(this.makeSubmenuItems(site));
     2161        return item;
     2162      });
     2163    }
     2164    makeSubmenuItems(siteElement) {
     2165      const submenuItems = [];
     2166      const submenu = siteElement.nextElementSibling.querySelector(`.ab-submenu`);
     2167      if (!submenu) {
     2168        return [];
     2169      }
     2170      const submenuLinks = submenu.querySelectorAll("a");
     2171      if (submenuLinks.length === 0) {
     2172        return [];
     2173      }
     2174      const submenuLinksArray = Array.from(submenuLinks);
     2175      submenuLinksArray.forEach((link) => {
     2176        const submenuItem = new class_submenu_item_default(link.innerText, link.href);
     2177        submenuItems.push(submenuItem);
     2178      });
     2179      return submenuItems;
     2180    }
     2181  };
     2182  var class_turbo_admin_mu_sites_default = TurboAdminMUSites;
     2183
     2184  // src/plugins/class-turbo-admin-oxygen-buillder.js
     2185  var TurboAdminOxygenBuilder = class extends class_turbo_admin_plugin_default {
     2186    constructor() {
     2187      super("OxygenBuilder");
     2188    }
     2189    shouldActivate() {
     2190      let oxygenLinkElem = document.getElementById("toplevel_page_ct_dashboard_page");
     2191      if (!oxygenLinkElem) {
     2192        oxygenLinkElem = document.getElementById("wp-admin-bar-oxygen_admin_bar_menu");
     2193      }
     2194      if (!oxygenLinkElem) {
     2195        oxygenLinkElem = Number(window.localStorage.getItem("ta-has-oxygen-builder"));
     2196      }
     2197      const hasOxygenBuilder = Boolean(oxygenLinkElem);
     2198      window.localStorage.setItem("ta-has-oxygen-builder", hasOxygenBuilder ? "1" : "0");
     2199      return hasOxygenBuilder;
     2200    }
     2201    activate() {
     2202      super.activate();
     2203    }
     2204    getAdditionalItemDefinitions() {
     2205      const editDefinition = new class_item_definition_default();
     2206      editDefinition.detectType = "dom";
     2207      editDefinition.detectSelector = "#ct-edit-template-builder";
     2208      editDefinition.itemTitleFunction = () => "Edit with Oxygen";
     2209      editDefinition.itemUrlFunction = (element) => element.href;
     2210      editDefinition.noCache = true;
     2211      const backToWpDefinition = new class_item_definition_default();
     2212      backToWpDefinition.detectType = "dom";
     2213      backToWpDefinition.detectSelector = ".oxygen-back-to-wp-menu .oxygen-toolbar-button-dropdown a:not(:last-of-type)";
     2214      backToWpDefinition.itemTitleFunction = (element) => "Back to WP: " + element.textContent;
     2215      backToWpDefinition.itemUrlFunction = (element) => {
     2216        if (element.href) {
     2217          return element.href;
     2218        } else {
     2219          let url = new URL(window.location.href);
     2220          return url.origin + url.pathname;
     2221        }
     2222      };
     2223      backToWpDefinition.noCache = true;
     2224      return [
     2225        editDefinition,
     2226        backToWpDefinition
     2227      ];
     2228    }
     2229  };
     2230  var class_turbo_admin_oxygen_buillder_default = TurboAdminOxygenBuilder;
    17882231
    17892232  // src/class-turbo-admin.js
    17902233  var TurboAdmin = class {
    17912234    constructor(options) {
     2235      this.doInit = true;
    17922236      if (document.getElementById("ta-command-palette-container")) {
    17932237        console.log("TurboAdmin already initialised - I won't make a second copy!");
     2238        this.doInit = false;
     2239        return globalThis.turboAdmin;
     2240      }
     2241      this.options = options;
     2242      this.plugins = {};
     2243      this.searchModes = {};
     2244      this.menuNeedsRefresh = false;
     2245    }
     2246    async init() {
     2247      if (!this.doInit) {
    17942248        return;
    17952249      }
    1796       this.options = options;
    1797     }
    1798     async init() {
     2250      new class_turbo_admin_barkeeper_default();
     2251      new class_turbo_admin_content_search_default();
     2252      new class_turbo_admin_plugins_default();
     2253      new class_turbo_admin_users_default();
     2254      new class_turbo_admin_mu_sites_default();
     2255      new class_turbo_admin_oxygen_buillder_default();
    17992256      this.wp = globalThis.taWp;
    18002257      this.menu = [];
    18012258      if (!this.wp.isBackend) {
    18022259        if (!this.wp.siteChanged) {
    1803           const savedMenu = window.localStorage.getItem("ta-palette-data");
    1804           if (savedMenu !== null) {
    1805             if (document.body.classList.contains("logged-in")) {
     2260          if (document.body.classList.contains("logged-in")) {
     2261            const savedMenu = window.localStorage.getItem("ta-palette-data");
     2262            if (savedMenu === null) {
     2263              this.menuNeedsRefresh = true;
     2264            } else {
    18062265              this.menu = JSON.parse(savedMenu);
     2266              if (!this.menu.some((item) => item.action.endsWith("upload.php"))) {
     2267                this.menuNeedsRefresh = true;
     2268              }
    18072269            }
    18082270          }
     
    18182280      this.addPalette();
    18192281      this.turboAdminPalette = new class_turbo_admin_palette_default(this.menu, this.options);
    1820       if (this.options["block-editor-fullscreen-disable"] === true) {
    1821         this.turboAdminFullscreenKill = new class_turbo_admin_wp_block_editor_fullscreen_kill_default();
    1822       }
    1823       if (this.options["block-editor-welcome-screen-kill"] === true) {
    1824         this.turboAdminWelcomeKill = new class_turbo_admin_wp_block_editor_welcome_guide_kill_default();
    1825       }
     2282    }
     2283    activatePlugins() {
     2284      Object.keys(this.plugins).forEach((plugin) => {
     2285        if (this.plugins[plugin].shouldActivate()) {
     2286          this.plugins[plugin].activate();
     2287        }
     2288      });
    18262289      if (this.options["list-table-keyboard-shortcuts"] === true) {
    18272290        this.turboAdminListTableShortcuts = new class_list_table_shortcuts_default();
    18282291      }
    1829       if (this.options["barkeeper"] === true) {
    1830         if (typeof browser !== "object") {
    1831           this.options["barkeeper-state"] = window.localStorage.getItem("turboAdminBarkeeperState");
    1832         }
    1833         this.turboAdminBarkeeper = new class_turbo_admin_barkeeper_default(this.options["barkeeper-state"]);
    1834       }
    18352292      if (globalThis.contentApi.userLoggedIn()) {
    18362293      }
     2294    }
     2295    hasActivatedPlugin(name) {
     2296      return Object.keys(this.plugins).includes(name) && this.plugins[name].activated;
    18372297    }
    18382298    getMenu() {
     
    18692329    addAdditionalMenuItems() {
    18702330      let extraItems = this.options.extraItems ?? [];
     2331      const pluginKeys = Object.keys(this.plugins);
     2332      for (let i = 0; i < pluginKeys.length; i++) {
     2333        extraItems = extraItems.concat(this.plugins[pluginKeys[i]].getAdditionalItemDefinitions());
     2334      }
    18712335      extraItems = extraItems.concat([
    18722336        {
     
    19422406          itemTitleFunction: (element) => "Network Admin: " + element.textContent,
    19432407          itemUrlFunction: (element) => element.href
    1944         },
    1945         {
    1946           detectType: "dom",
    1947           detectSelector: "#wp-admin-bar-my-sites #wp-admin-bar-my-sites-list .ab-submenu a",
    1948           itemTitleFunction: (element) => "Sites: " + element.closest(".menupop").querySelector("a").innerText + " - " + element.innerText,
    1949           itemUrlFunction: (element) => element.href
    1950         },
    1951         {
    1952           detectType: "dom",
    1953           detectSelector: "#ct-edit-template-builder",
    1954           itemTitleFunction: () => "Edit with Oxygen",
    1955           itemUrlFunction: (element) => element.href,
    1956           noCache: true
    1957         },
    1958         {
    1959           detectType: "dom",
    1960           detectSelector: ".oxygen-back-to-wp-menu .oxygen-toolbar-button-dropdown a:not(:last-of-type)",
    1961           itemTitleFunction: (element) => "Back to WP: " + element.textContent,
    1962           itemUrlFunction: (element) => {
    1963             if (element.href) {
    1964               return element.href;
    1965             } else {
    1966               let url = new URL(window.location.href);
    1967               return url.origin + url.pathname;
    1968             }
    1969           },
    1970           noCache: true
    19712408        }
    19722409      ]);
     
    20052442      const palette = document.createElement("div");
    20062443      palette.id = "ta-command-palette";
     2444      const paletteNotice = document.createElement("div");
     2445      paletteNotice.id = "ta-command-palette-notice";
     2446      const tabNotice = document.createElement("div");
     2447      tabNotice.id = "ta-command-palette-tab-notice";
     2448      const tabNoticeText = document.createElement("span");
     2449      tabNoticeText.id = "ta-command-palette-tab-notice-text";
     2450      const tabNoticeButton = document.createElement("span");
     2451      tabNoticeButton.id = "ta-command-palette-tab-notice-button";
     2452      tabNoticeButton.innerText = "Tab";
    20072453      const input = document.createElement("input");
    20082454      input.id = "ta-command-palette-input";
     
    20102456      input.type = "text";
    20112457      input.setAttribute("autocomplete", "off");
     2458      const searchModeTag = document.createElement("div");
     2459      searchModeTag.id = "ta-command-palette-search-mode-tag";
     2460      const listContainer = document.createElement("div");
     2461      listContainer.id = "ta-command-palette-items-container";
    20122462      const list = document.createElement("ul");
    20132463      list.id = "ta-command-palette-items";
     2464      const submenuContainer = document.createElement("div");
     2465      submenuContainer.id = "ta-command-palette-submenu-container";
    20142466      container.appendChild(palette);
     2467      palette.appendChild(searchModeTag);
     2468      palette.appendChild(paletteNotice);
     2469      tabNotice.appendChild(tabNoticeText);
     2470      tabNotice.appendChild(tabNoticeButton);
     2471      palette.appendChild(tabNotice);
    20152472      palette.appendChild(input);
    2016       palette.appendChild(list);
     2473      listContainer.appendChild(list);
     2474      listContainer.appendChild(submenuContainer);
     2475      palette.appendChild(listContainer);
    20172476      if (document.getElementById("wpadminbar") && this.options["admin-bar-search"] === true) {
    20182477        const paletteLi = document.createElement("li");
     
    20252484        placeholder.innerText = this.buildShortcutKeysString();
    20262485        placeholder.addEventListener("click", (e) => input.focus());
    2027         palette.insertBefore(placeholder, list);
     2486        palette.insertBefore(placeholder, listContainer);
    20282487      } else {
    20292488        document.querySelector(this.options.appendToElement ?? "body").appendChild(container);
    20302489      }
     2490    }
     2491    registerPlugin(plugin) {
     2492      console.log("Registering plugin " + plugin.name);
     2493      this.plugins[plugin.name] = plugin;
     2494    }
     2495    registerSearchMode(searchMode) {
     2496      console.log("Registering search mode with keyword " + searchMode.keyword);
     2497      globalThis.turboAdmin.searchModes[searchMode.keyword] = searchMode;
    20312498    }
    20322499    buildShortcutKeysString() {
     
    20452512        keysString += "Shift-";
    20462513      }
    2047       keysString += shortcut.key.toUpperCase();
     2514      keysString += shortcut.key;
    20482515      return keysString;
    20492516    }
     
    21732640  var class_wp_default = Wp;
    21742641
     2642  // src/apis/class-woocommerce-api.js
     2643  var WoocommerceApi = class {
     2644    constructor() {
     2645      this.cache = {};
     2646    }
     2647    async getOrders(searchString) {
     2648      if (this.cache["orders-" + searchString] !== void 0) {
     2649        return this.cache["orders-" + searchString];
     2650      }
     2651      const response = await this.wooGet("orders", {
     2652        search: searchString,
     2653        per_page: 100
     2654      });
     2655      if (response === false) {
     2656        return false;
     2657      }
     2658      const result = await response.json();
     2659      this.cache["orders-" + searchString] = result;
     2660      return result;
     2661    }
     2662    async getOrder(orderId) {
     2663      if (this.cache["order-" + orderId] !== void 0) {
     2664        return this.cache["order-" + orderId];
     2665      }
     2666      const response = await this.wooGet(`orders/${orderId}`);
     2667      if (response === false) {
     2668        return false;
     2669      }
     2670      const result = await response.json();
     2671      let resultAsArray = [result];
     2672      this.cache["order-" + orderId] = resultAsArray;
     2673      return resultAsArray;
     2674    }
     2675    async getCustomers(searchString) {
     2676      if (this.cache["customers-" + searchString] !== void 0) {
     2677        return this.cache["customers-" + searchString];
     2678      }
     2679      const response = await this.wooGet("customers", {
     2680        search: searchString,
     2681        per_page: 100,
     2682        role: "all"
     2683      });
     2684      if (response === false) {
     2685        return false;
     2686      }
     2687      const result = await response.json();
     2688      this.cache["customers-" + searchString] = result;
     2689      return result;
     2690    }
     2691    async wooGet(path, data = {}) {
     2692      const wooApiBase = globalThis.contentApi.apiRoot + "wc/v3/";
     2693      const init = {
     2694        method: "GET",
     2695        headers: {},
     2696        mode: "cors",
     2697        cache: "no-store",
     2698        credentials: "include"
     2699      };
     2700      if (globalThis.contentApi.apiNonce) {
     2701        data._wpnonce = globalThis.contentApi.apiNonce;
     2702      }
     2703      const params = globalThis.contentApi.makeParamString(data);
     2704      const response = await fetch(`${wooApiBase}${path}/?${params}`, init);
     2705      if (response.status === 404) {
     2706        return false;
     2707      }
     2708      if (response.status < 200 || response.status >= 300) {
     2709        globalThis.turboAdmin.turboAdminPalette.showPaletteNotice("WooCommerce API Error. Try visiting the dashboard to refresh things.");
     2710      }
     2711      return response;
     2712    }
     2713  };
     2714  var class_woocommerce_api_default = WoocommerceApi;
     2715
     2716  // src/apis/class-gravity-forms-api.js
     2717  var GravityFormsApi = class {
     2718    constructor() {
     2719      this.cache = {};
     2720    }
     2721    async getForms(searchString) {
     2722      if (this.cache["gf-forms-" + searchString] !== void 0) {
     2723        return this.cache["gf-forms-" + searchString];
     2724      }
     2725      const response = await this.gfGet("forms", {});
     2726      const result = await response.json();
     2727      const searchStringLowerCase = searchString.toLowerCase();
     2728      const formIds = Object.keys(result);
     2729      for (let k = 0; k < formIds.length; k++) {
     2730        const thisId = formIds[k];
     2731        if (!result[thisId].title.toLowerCase().includes(searchStringLowerCase)) {
     2732          delete result[thisId];
     2733        }
     2734      }
     2735      this.cache["gf-forms-" + searchString] = result;
     2736      return result;
     2737    }
     2738    async gfGet(path, data = {}) {
     2739      const gfApiBase = globalThis.contentApi.apiRoot + "gf/v2/";
     2740      const init = {
     2741        method: "GET",
     2742        headers: {},
     2743        mode: "cors",
     2744        cache: "no-store",
     2745        credentials: "include"
     2746      };
     2747      if (globalThis.contentApi.apiNonce) {
     2748        data._wpnonce = globalThis.contentApi.apiNonce;
     2749      }
     2750      const params = globalThis.contentApi.makeParamString(data);
     2751      const response = await fetch(`${gfApiBase}${path}/?${params}`);
     2752      if (response.status < 200 || response.status >= 300) {
     2753        globalThis.turboAdmin.turboAdminPalette.showPaletteNotice("Gravity Forms API Error. Try visiting the dashboard to refresh things.");
     2754      }
     2755      return response;
     2756    }
     2757  };
     2758  var class_gravity_forms_api_default = GravityFormsApi;
     2759
    21752760  // src/main.js
    21762761  var taStorageKey = "turbo-admin-settings";
    21772762  async function taInit(settings) {
     2763    if (typeof globalThis.turboAdmin !== "undefined") {
     2764      return;
     2765    }
    21782766    globalThis.turboAdmin = null;
    21792767    if (typeof settings[taStorageKey] === "undefined") {
     
    21822770    }
    21832771    globalThis.turboAdminOptions = settings[taStorageKey];
     2772    console.log("Preparing Turbo Admin");
    21842773    globalThis.taWp = new class_wp_default();
    21852774    await globalThis.taWp.completeInit();
     
    21872776    globalThis.contentApi = new class_content_api_default();
    21882777    await globalThis.contentApi.discoverApiRoot();
     2778    await globalThis.contentApi.discoverPostTypes();
     2779    globalThis.woocommerceApi = new class_woocommerce_api_default();
     2780    globalThis.gravityFormsApi = new class_gravity_forms_api_default();
    21892781    console.log("Turbo Admin: Content API is initialised");
    21902782    globalThis.turboAdmin = new class_turbo_admin_default(globalThis.turboAdminOptions);
    21912783    await globalThis.turboAdmin.init();
     2784    await globalThis.turboAdmin.activatePlugins();
    21922785    if (settings[taStorageKey]["hide-notices"]) {
    21932786      globalThis.turboAdminWpNotices = new class_turbo_admin_wp_notices_default(settings[taStorageKey].rememberedNoticeIds);
  • turbo-admin/tags/1.12.0/dist/main.min.js.map

    r2703739 r2835882  
    11{
    22  "version": 3,
    3   "sources": ["../src/fuse-6.4.6.js", "../src/class-turbo-admin-palette.js", "../src/class-turbo-admin-menu-item.js", "../src/class-storage.js", "../src/class-content-api.js", "../src/class-turbo-admin-wp-block-editor-fullscreen-kill.js", "../src/class-turbo-admin-wp-block-editor-welcome-guide-kill.js", "../src/class-turbo-admin-wp-notices.js", "../src/class-list-table-shortcuts.js", "../src/class-turbo-admin-barkeeper.js", "../src/class-turbo-admin.js", "../src/class-wp.js", "../src/main.js"],
    4   "sourcesContent": ["/**\n * Fuse.js v6.4.6 - Lightweight fuzzy-search (http://fusejs.io)\n *\n * Copyright (c) 2021 Kiro Risk (http://kiro.me)\n * All Rights Reserved. Apache Software License 2.0\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\nvar e, t; e = this, t = function () { \"use strict\"; function e(t) { return (e = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (e) { return typeof e } : function (e) { return e && \"function\" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? \"symbol\" : typeof e })(t) } function t(e, t) { if (!(e instanceof t)) throw new TypeError(\"Cannot call a class as a function\") } function n(e, t) { for (var n = 0; n < t.length; n++) { var r = t[n]; r.enumerable = r.enumerable || !1, r.configurable = !0, \"value\" in r && (r.writable = !0), Object.defineProperty(e, r.key, r) } } function r(e, t, r) { return t && n(e.prototype, t), r && n(e, r), e } function i(e, t, n) { return t in e ? Object.defineProperty(e, t, { value: n, enumerable: !0, configurable: !0, writable: !0 }) : e[t] = n, e } function o(e, t) { var n = Object.keys(e); if (Object.getOwnPropertySymbols) { var r = Object.getOwnPropertySymbols(e); t && (r = r.filter((function (t) { return Object.getOwnPropertyDescriptor(e, t).enumerable }))), n.push.apply(n, r) } return n } function c(e) { for (var t = 1; t < arguments.length; t++) { var n = null != arguments[t] ? arguments[t] : {}; t % 2 ? o(Object(n), !0).forEach((function (t) { i(e, t, n[t]) })) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(n)) : o(Object(n)).forEach((function (t) { Object.defineProperty(e, t, Object.getOwnPropertyDescriptor(n, t)) })) } return e } function a(e, t) { if (\"function\" != typeof t && null !== t) throw new TypeError(\"Super expression must either be null or a function\"); e.prototype = Object.create(t && t.prototype, { constructor: { value: e, writable: !0, configurable: !0 } }), t && u(e, t) } function s(e) { return (s = Object.setPrototypeOf ? Object.getPrototypeOf : function (e) { return e.__proto__ || Object.getPrototypeOf(e) })(e) } function u(e, t) { return (u = Object.setPrototypeOf || function (e, t) { return e.__proto__ = t, e })(e, t) } function h(e, t) { return !t || \"object\" != typeof t && \"function\" != typeof t ? function (e) { if (void 0 === e) throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); return e }(e) : t } function f(e) { var t = function () { if (\"undefined\" == typeof Reflect || !Reflect.construct) return !1; if (Reflect.construct.sham) return !1; if (\"function\" == typeof Proxy) return !0; try { return Date.prototype.toString.call(Reflect.construct(Date, [], (function () { }))), !0 } catch (e) { return !1 } }(); return function () { var n, r = s(e); if (t) { var i = s(this).constructor; n = Reflect.construct(r, arguments, i) } else n = r.apply(this, arguments); return h(this, n) } } function l(e) { return function (e) { if (Array.isArray(e)) return d(e) }(e) || function (e) { if (\"undefined\" != typeof Symbol && Symbol.iterator in Object(e)) return Array.from(e) }(e) || function (e, t) { if (e) { if (\"string\" == typeof e) return d(e, t); var n = Object.prototype.toString.call(e).slice(8, -1); return \"Object\" === n && e.constructor && (n = e.constructor.name), \"Map\" === n || \"Set\" === n ? Array.from(e) : \"Arguments\" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n) ? d(e, t) : void 0 } }(e) || function () { throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\") }() } function d(e, t) { (null == t || t > e.length) && (t = e.length); for (var n = 0, r = new Array(t); n < t; n++)r[n] = e[n]; return r } function v(e) { return Array.isArray ? Array.isArray(e) : \"[object Array]\" === b(e) } function g(e) { return \"string\" == typeof e } function y(e) { return \"number\" == typeof e } function p(e) { return !0 === e || !1 === e || function (e) { return m(e) && null !== e }(e) && \"[object Boolean]\" == b(e) } function m(t) { return \"object\" === e(t) } function k(e) { return null != e } function M(e) { return !e.trim().length } function b(e) { return null == e ? void 0 === e ? \"[object Undefined]\" : \"[object Null]\" : Object.prototype.toString.call(e) } var x = function (e) { return \"Invalid value for key \".concat(e) }, L = function (e) { return \"Pattern length exceeds max of \".concat(e, \".\") }, S = Object.prototype.hasOwnProperty, w = function () { function e(n) { var r = this; t(this, e), this._keys = [], this._keyMap = {}; var i = 0; n.forEach((function (e) { var t = _(e); i += t.weight, r._keys.push(t), r._keyMap[t.id] = t, i += t.weight })), this._keys.forEach((function (e) { e.weight /= i })) } return r(e, [{ key: \"get\", value: function (e) { return this._keyMap[e] } }, { key: \"keys\", value: function () { return this._keys } }, { key: \"toJSON\", value: function () { return JSON.stringify(this._keys) } }]), e }(); function _(e) { var t = null, n = null, r = null, i = 1; if (g(e) || v(e)) r = e, t = O(e), n = j(e); else { if (!S.call(e, \"name\")) throw new Error(function (e) { return \"Missing \".concat(e, \" property in key\") }(\"name\")); var o = e.name; if (r = o, S.call(e, \"weight\") && (i = e.weight) <= 0) throw new Error(function (e) { return \"Property 'weight' in key '\".concat(e, \"' must be a positive integer\") }(o)); t = O(o), n = j(o) } return { path: t, id: n, weight: i, src: r } } function O(e) { return v(e) ? e : e.split(\".\") } function j(e) { return v(e) ? e.join(\".\") : e } var A = c({}, { isCaseSensitive: !1, includeScore: !1, keys: [], shouldSort: !0, sortFn: function (e, t) { return e.score === t.score ? e.idx < t.idx ? -1 : 1 : e.score < t.score ? -1 : 1 } }, {}, { includeMatches: !1, findAllMatches: !1, minMatchCharLength: 1 }, {}, { location: 0, threshold: .6, distance: 100 }, {}, { useExtendedSearch: !1, getFn: function (e, t) { var n = [], r = !1; return function e(t, i, o) { if (k(t)) if (i[o]) { var c = t[i[o]]; if (!k(c)) return; if (o === i.length - 1 && (g(c) || y(c) || p(c))) n.push(function (e) { return null == e ? \"\" : function (e) { if (\"string\" == typeof e) return e; var t = e + \"\"; return \"0\" == t && 1 / e == -1 / 0 ? \"-0\" : t }(e) }(c)); else if (v(c)) { r = !0; for (var a = 0, s = c.length; a < s; a += 1)e(c[a], i, o + 1) } else i.length && e(c, i, o + 1) } else n.push(t) }(e, g(t) ? t.split(\".\") : t, 0), r ? n : n[0] }, ignoreLocation: !1, ignoreFieldNorm: !1 }), I = /[^ ]+/g; function C() { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : 3, t = new Map, n = Math.pow(10, e); return { get: function (e) { var r = e.match(I).length; if (t.has(r)) return t.get(r); var i = 1 / Math.sqrt(r), o = parseFloat(Math.round(i * n) / n); return t.set(r, o), o }, clear: function () { t.clear() } } } var E = function () { function e() { var n = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}, r = n.getFn, i = void 0 === r ? A.getFn : r; t(this, e), this.norm = C(3), this.getFn = i, this.isCreated = !1, this.setIndexRecords() } return r(e, [{ key: \"setSources\", value: function () { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : []; this.docs = e } }, { key: \"setIndexRecords\", value: function () { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : []; this.records = e } }, { key: \"setKeys\", value: function () { var e = this, t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : []; this.keys = t, this._keysMap = {}, t.forEach((function (t, n) { e._keysMap[t.id] = n })) } }, { key: \"create\", value: function () { var e = this; !this.isCreated && this.docs.length && (this.isCreated = !0, g(this.docs[0]) ? this.docs.forEach((function (t, n) { e._addString(t, n) })) : this.docs.forEach((function (t, n) { e._addObject(t, n) })), this.norm.clear()) } }, { key: \"add\", value: function (e) { var t = this.size(); g(e) ? this._addString(e, t) : this._addObject(e, t) } }, { key: \"removeAt\", value: function (e) { this.records.splice(e, 1); for (var t = e, n = this.size(); t < n; t += 1)this.records[t].i -= 1 } }, { key: \"getValueForItemAtKeyId\", value: function (e, t) { return e[this._keysMap[t]] } }, { key: \"size\", value: function () { return this.records.length } }, { key: \"_addString\", value: function (e, t) { if (k(e) && !M(e)) { var n = { v: e, i: t, n: this.norm.get(e) }; this.records.push(n) } } }, { key: \"_addObject\", value: function (e, t) { var n = this, r = { i: t, $: {} }; this.keys.forEach((function (t, i) { var o = n.getFn(e, t.path); if (k(o)) if (v(o)) !function () { for (var e = [], t = [{ nestedArrIndex: -1, value: o }]; t.length;) { var c = t.pop(), a = c.nestedArrIndex, s = c.value; if (k(s)) if (g(s) && !M(s)) { var u = { v: s, i: a, n: n.norm.get(s) }; e.push(u) } else v(s) && s.forEach((function (e, n) { t.push({ nestedArrIndex: n, value: e }) })) } r.$[i] = e }(); else if (!M(o)) { var c = { v: o, n: n.norm.get(o) }; r.$[i] = c } })), this.records.push(r) } }, { key: \"toJSON\", value: function () { return { keys: this.keys, records: this.records } } }]), e }(); function $(e, t) { var n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, r = n.getFn, i = void 0 === r ? A.getFn : r, o = new E({ getFn: i }); return o.setKeys(e.map(_)), o.setSources(t), o.create(), o } function R(e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.errors, r = void 0 === n ? 0 : n, i = t.currentLocation, o = void 0 === i ? 0 : i, c = t.expectedLocation, a = void 0 === c ? 0 : c, s = t.distance, u = void 0 === s ? A.distance : s, h = t.ignoreLocation, f = void 0 === h ? A.ignoreLocation : h, l = r / e.length; if (f) return l; var d = Math.abs(a - o); return u ? l + d / u : d ? 1 : l } function F() { for (var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : [], t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : A.minMatchCharLength, n = [], r = -1, i = -1, o = 0, c = e.length; o < c; o += 1) { var a = e[o]; a && -1 === r ? r = o : a || -1 === r || ((i = o - 1) - r + 1 >= t && n.push([r, i]), r = -1) } return e[o - 1] && o - r >= t && n.push([r, o - 1]), n } function P(e) { for (var t = {}, n = 0, r = e.length; n < r; n += 1) { var i = e.charAt(n); t[i] = (t[i] || 0) | 1 << r - n - 1 } return t } var N = function () { function e(n) { var r = this, i = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, o = i.location, c = void 0 === o ? A.location : o, a = i.threshold, s = void 0 === a ? A.threshold : a, u = i.distance, h = void 0 === u ? A.distance : u, f = i.includeMatches, l = void 0 === f ? A.includeMatches : f, d = i.findAllMatches, v = void 0 === d ? A.findAllMatches : d, g = i.minMatchCharLength, y = void 0 === g ? A.minMatchCharLength : g, p = i.isCaseSensitive, m = void 0 === p ? A.isCaseSensitive : p, k = i.ignoreLocation, M = void 0 === k ? A.ignoreLocation : k; if (t(this, e), this.options = { location: c, threshold: s, distance: h, includeMatches: l, findAllMatches: v, minMatchCharLength: y, isCaseSensitive: m, ignoreLocation: M }, this.pattern = m ? n : n.toLowerCase(), this.chunks = [], this.pattern.length) { var b = function (e, t) { r.chunks.push({ pattern: e, alphabet: P(e), startIndex: t }) }, x = this.pattern.length; if (x > 32) { for (var L = 0, S = x % 32, w = x - S; L < w;)b(this.pattern.substr(L, 32), L), L += 32; if (S) { var _ = x - 32; b(this.pattern.substr(_), _) } } else b(this.pattern, 0) } } return r(e, [{ key: \"searchIn\", value: function (e) { var t = this.options, n = t.isCaseSensitive, r = t.includeMatches; if (n || (e = e.toLowerCase()), this.pattern === e) { var i = { isMatch: !0, score: 0 }; return r && (i.indices = [[0, e.length - 1]]), i } var o = this.options, c = o.location, a = o.distance, s = o.threshold, u = o.findAllMatches, h = o.minMatchCharLength, f = o.ignoreLocation, d = [], v = 0, g = !1; this.chunks.forEach((function (t) { var n = t.pattern, i = t.alphabet, o = t.startIndex, y = function (e, t, n) { var r = arguments.length > 3 && void 0 !== arguments[3] ? arguments[3] : {}, i = r.location, o = void 0 === i ? A.location : i, c = r.distance, a = void 0 === c ? A.distance : c, s = r.threshold, u = void 0 === s ? A.threshold : s, h = r.findAllMatches, f = void 0 === h ? A.findAllMatches : h, l = r.minMatchCharLength, d = void 0 === l ? A.minMatchCharLength : l, v = r.includeMatches, g = void 0 === v ? A.includeMatches : v, y = r.ignoreLocation, p = void 0 === y ? A.ignoreLocation : y; if (t.length > 32) throw new Error(L(32)); for (var m, k = t.length, M = e.length, b = Math.max(0, Math.min(o, M)), x = u, S = b, w = d > 1 || g, _ = w ? Array(M) : []; (m = e.indexOf(t, S)) > -1;) { var O = R(t, { currentLocation: m, expectedLocation: b, distance: a, ignoreLocation: p }); if (x = Math.min(O, x), S = m + k, w) for (var j = 0; j < k;)_[m + j] = 1, j += 1 } S = -1; for (var I = [], C = 1, E = k + M, $ = 1 << k - 1, P = 0; P < k; P += 1) { for (var N = 0, D = E; N < D;) { var z = R(t, { errors: P, currentLocation: b + D, expectedLocation: b, distance: a, ignoreLocation: p }); z <= x ? N = D : E = D, D = Math.floor((E - N) / 2 + N) } E = D; var K = Math.max(1, b - D + 1), q = f ? M : Math.min(b + D, M) + k, W = Array(q + 2); W[q + 1] = (1 << P) - 1; for (var J = q; J >= K; J -= 1) { var T = J - 1, U = n[e.charAt(T)]; if (w && (_[T] = +!!U), W[J] = (W[J + 1] << 1 | 1) & U, P && (W[J] |= (I[J + 1] | I[J]) << 1 | 1 | I[J + 1]), W[J] & $ && (C = R(t, { errors: P, currentLocation: T, expectedLocation: b, distance: a, ignoreLocation: p })) <= x) { if (x = C, (S = T) <= b) break; K = Math.max(1, 2 * b - S) } } var V = R(t, { errors: P + 1, currentLocation: b, expectedLocation: b, distance: a, ignoreLocation: p }); if (V > x) break; I = W } var B = { isMatch: S >= 0, score: Math.max(.001, C) }; if (w) { var G = F(_, d); G.length ? g && (B.indices = G) : B.isMatch = !1 } return B }(e, n, i, { location: c + o, distance: a, threshold: s, findAllMatches: u, minMatchCharLength: h, includeMatches: r, ignoreLocation: f }), p = y.isMatch, m = y.score, k = y.indices; p && (g = !0), v += m, p && k && (d = [].concat(l(d), l(k))) })); var y = { isMatch: g, score: g ? v / this.chunks.length : 1 }; return g && r && (y.indices = d), y } }]), e }(), D = function () { function e(n) { t(this, e), this.pattern = n } return r(e, [{ key: \"search\", value: function () { } }], [{ key: \"isMultiMatch\", value: function (e) { return z(e, this.multiRegex) } }, { key: \"isSingleMatch\", value: function (e) { return z(e, this.singleRegex) } }]), e }(); function z(e, t) { var n = e.match(t); return n ? n[1] : null } var K = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = e === this.pattern; return { isMatch: t, score: t ? 0 : 1, indices: [0, this.pattern.length - 1] } } }], [{ key: \"type\", get: function () { return \"exact\" } }, { key: \"multiRegex\", get: function () { return /^=\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^=(.*)$/ } }]), i }(D), q = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = -1 === e.indexOf(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"inverse-exact\" } }, { key: \"multiRegex\", get: function () { return /^!\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^!(.*)$/ } }]), i }(D), W = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = e.startsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, this.pattern.length - 1] } } }], [{ key: \"type\", get: function () { return \"prefix-exact\" } }, { key: \"multiRegex\", get: function () { return /^\\^\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^\\^(.*)$/ } }]), i }(D), J = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = !e.startsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"inverse-prefix-exact\" } }, { key: \"multiRegex\", get: function () { return /^!\\^\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^!\\^(.*)$/ } }]), i }(D), T = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = e.endsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [e.length - this.pattern.length, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"suffix-exact\" } }, { key: \"multiRegex\", get: function () { return /^\"(.*)\"\\$$/ } }, { key: \"singleRegex\", get: function () { return /^(.*)\\$$/ } }]), i }(D), U = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = !e.endsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"inverse-suffix-exact\" } }, { key: \"multiRegex\", get: function () { return /^!\"(.*)\"\\$$/ } }, { key: \"singleRegex\", get: function () { return /^!(.*)\\$$/ } }]), i }(D), V = function (e) { a(i, e); var n = f(i); function i(e) { var r, o = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, c = o.location, a = void 0 === c ? A.location : c, s = o.threshold, u = void 0 === s ? A.threshold : s, h = o.distance, f = void 0 === h ? A.distance : h, l = o.includeMatches, d = void 0 === l ? A.includeMatches : l, v = o.findAllMatches, g = void 0 === v ? A.findAllMatches : v, y = o.minMatchCharLength, p = void 0 === y ? A.minMatchCharLength : y, m = o.isCaseSensitive, k = void 0 === m ? A.isCaseSensitive : m, M = o.ignoreLocation, b = void 0 === M ? A.ignoreLocation : M; return t(this, i), (r = n.call(this, e))._bitapSearch = new N(e, { location: a, threshold: u, distance: f, includeMatches: d, findAllMatches: g, minMatchCharLength: p, isCaseSensitive: k, ignoreLocation: b }), r } return r(i, [{ key: \"search\", value: function (e) { return this._bitapSearch.searchIn(e) } }], [{ key: \"type\", get: function () { return \"fuzzy\" } }, { key: \"multiRegex\", get: function () { return /^\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^(.*)$/ } }]), i }(D), B = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { for (var t, n = 0, r = [], i = this.pattern.length; (t = e.indexOf(this.pattern, n)) > -1;)n = t + i, r.push([t, n - 1]); var o = !!r.length; return { isMatch: o, score: o ? 0 : 1, indices: r } } }], [{ key: \"type\", get: function () { return \"include\" } }, { key: \"multiRegex\", get: function () { return /^'\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^'(.*)$/ } }]), i }(D), G = [K, B, W, J, U, T, q, V], H = G.length, Q = / +(?=([^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)/; function X(e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}; return e.split(\"|\").map((function (e) { for (var n = e.trim().split(Q).filter((function (e) { return e && !!e.trim() })), r = [], i = 0, o = n.length; i < o; i += 1) { for (var c = n[i], a = !1, s = -1; !a && ++s < H;) { var u = G[s], h = u.isMultiMatch(c); h && (r.push(new u(h, t)), a = !0) } if (!a) for (s = -1; ++s < H;) { var f = G[s], l = f.isSingleMatch(c); if (l) { r.push(new f(l, t)); break } } } return r })) } var Y = new Set([V.type, B.type]), Z = function () { function e(n) { var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, i = r.isCaseSensitive, o = void 0 === i ? A.isCaseSensitive : i, c = r.includeMatches, a = void 0 === c ? A.includeMatches : c, s = r.minMatchCharLength, u = void 0 === s ? A.minMatchCharLength : s, h = r.ignoreLocation, f = void 0 === h ? A.ignoreLocation : h, l = r.findAllMatches, d = void 0 === l ? A.findAllMatches : l, v = r.location, g = void 0 === v ? A.location : v, y = r.threshold, p = void 0 === y ? A.threshold : y, m = r.distance, k = void 0 === m ? A.distance : m; t(this, e), this.query = null, this.options = { isCaseSensitive: o, includeMatches: a, minMatchCharLength: u, findAllMatches: d, ignoreLocation: f, location: g, threshold: p, distance: k }, this.pattern = o ? n : n.toLowerCase(), this.query = X(this.pattern, this.options) } return r(e, [{ key: \"searchIn\", value: function (e) { var t = this.query; if (!t) return { isMatch: !1, score: 1 }; var n = this.options, r = n.includeMatches; e = n.isCaseSensitive ? e : e.toLowerCase(); for (var i = 0, o = [], c = 0, a = 0, s = t.length; a < s; a += 1) { var u = t[a]; o.length = 0, i = 0; for (var h = 0, f = u.length; h < f; h += 1) { var d = u[h], v = d.search(e), g = v.isMatch, y = v.indices, p = v.score; if (!g) { c = 0, i = 0, o.length = 0; break } if (i += 1, c += p, r) { var m = d.constructor.type; Y.has(m) ? o = [].concat(l(o), l(y)) : o.push(y) } } if (i) { var k = { isMatch: !0, score: c / i }; return r && (k.indices = o), k } } return { isMatch: !1, score: 1 } } }], [{ key: \"condition\", value: function (e, t) { return t.useExtendedSearch } }]), e }(), ee = []; function te(e, t) { for (var n = 0, r = ee.length; n < r; n += 1) { var i = ee[n]; if (i.condition(e, t)) return new i(e, t) } return new N(e, t) } var ne = \"$and\", re = \"$or\", ie = \"$path\", oe = \"$val\", ce = function (e) { return !(!e[ne] && !e[re]) }, ae = function (e) { return !!e[ie] }, se = function (e) { return !v(e) && m(e) && !ce(e) }, ue = function (e) { return i({}, ne, Object.keys(e).map((function (t) { return i({}, t, e[t]) }))) }; function he(e, t) { var n = t.ignoreFieldNorm, r = void 0 === n ? A.ignoreFieldNorm : n; e.forEach((function (e) { var t = 1; e.matches.forEach((function (e) { var n = e.key, i = e.norm, o = e.score, c = n ? n.weight : null; t *= Math.pow(0 === o && c ? Number.EPSILON : o, (c || 1) * (r ? 1 : i)) })), e.score = t })) } function fe(e, t) { var n = e.matches; t.matches = [], k(n) && n.forEach((function (e) { if (k(e.indices) && e.indices.length) { var n = { indices: e.indices, value: e.value }; e.key && (n.key = e.key.src), e.idx > -1 && (n.refIndex = e.idx), t.matches.push(n) } })) } function le(e, t) { t.score = e.score } function de(e, t) { var n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, r = n.includeMatches, i = void 0 === r ? A.includeMatches : r, o = n.includeScore, c = void 0 === o ? A.includeScore : o, a = []; return i && a.push(fe), c && a.push(le), e.map((function (e) { var n = e.idx, r = { item: t[n], refIndex: n }; return a.length && a.forEach((function (t) { t(e, r) })), r })) } var ve = function () { function e(n) { var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, i = arguments.length > 2 ? arguments[2] : void 0; t(this, e), this.options = c({}, A, {}, r), this.options.useExtendedSearch, this._keyStore = new w(this.options.keys), this.setCollection(n, i) } return r(e, [{ key: \"setCollection\", value: function (e, t) { if (this._docs = e, t && !(t instanceof E)) throw new Error(\"Incorrect 'index' type\"); this._myIndex = t || $(this.options.keys, this._docs, { getFn: this.options.getFn }) } }, { key: \"add\", value: function (e) { k(e) && (this._docs.push(e), this._myIndex.add(e)) } }, { key: \"remove\", value: function () { for (var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : function () { return !1 }, t = [], n = 0, r = this._docs.length; n < r; n += 1) { var i = this._docs[n]; e(i, n) && (this.removeAt(n), n -= 1, r -= 1, t.push(i)) } return t } }, { key: \"removeAt\", value: function (e) { this._docs.splice(e, 1), this._myIndex.removeAt(e) } }, { key: \"getIndex\", value: function () { return this._myIndex } }, { key: \"search\", value: function (e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.limit, r = void 0 === n ? -1 : n, i = this.options, o = i.includeMatches, c = i.includeScore, a = i.shouldSort, s = i.sortFn, u = i.ignoreFieldNorm, h = g(e) ? g(this._docs[0]) ? this._searchStringList(e) : this._searchObjectList(e) : this._searchLogical(e); return he(h, { ignoreFieldNorm: u }), a && h.sort(s), y(r) && r > -1 && (h = h.slice(0, r)), de(h, this._docs, { includeMatches: o, includeScore: c }) } }, { key: \"_searchStringList\", value: function (e) { var t = te(e, this.options), n = this._myIndex.records, r = []; return n.forEach((function (e) { var n = e.v, i = e.i, o = e.n; if (k(n)) { var c = t.searchIn(n), a = c.isMatch, s = c.score, u = c.indices; a && r.push({ item: n, idx: i, matches: [{ score: s, value: n, norm: o, indices: u }] }) } })), r } }, { key: \"_searchLogical\", value: function (e) { var t = this, n = function (e, t) { var n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, r = n.auto, i = void 0 === r || r, o = function e(n) { var r = Object.keys(n), o = ae(n); if (!o && r.length > 1 && !ce(n)) return e(ue(n)); if (se(n)) { var c = o ? n[ie] : r[0], a = o ? n[oe] : n[c]; if (!g(a)) throw new Error(x(c)); var s = { keyId: j(c), pattern: a }; return i && (s.searcher = te(a, t)), s } var u = { children: [], operator: r[0] }; return r.forEach((function (t) { var r = n[t]; v(r) && r.forEach((function (t) { u.children.push(e(t)) })) })), u }; return ce(e) || (e = ue(e)), o(e) }(e, this.options), r = this._myIndex.records, i = {}, o = []; return r.forEach((function (e) { var r = e.$, c = e.i; if (k(r)) { var a = function e(n, r, i) { if (!n.children) { var o = n.keyId, c = n.searcher, a = t._findMatches({ key: t._keyStore.get(o), value: t._myIndex.getValueForItemAtKeyId(r, o), searcher: c }); return a && a.length ? [{ idx: i, item: r, matches: a }] : [] } switch (n.operator) { case ne: for (var s = [], u = 0, h = n.children.length; u < h; u += 1) { var f = e(n.children[u], r, i); if (!f.length) return []; s.push.apply(s, l(f)) } return s; case re: for (var d = [], v = 0, g = n.children.length; v < g; v += 1) { var y = e(n.children[v], r, i); if (y.length) { d.push.apply(d, l(y)); break } } return d } }(n, r, c); a.length && (i[c] || (i[c] = { idx: c, item: r, matches: [] }, o.push(i[c])), a.forEach((function (e) { var t, n = e.matches; (t = i[c].matches).push.apply(t, l(n)) }))) } })), o } }, { key: \"_searchObjectList\", value: function (e) { var t = this, n = te(e, this.options), r = this._myIndex, i = r.keys, o = r.records, c = []; return o.forEach((function (e) { var r = e.$, o = e.i; if (k(r)) { var a = []; i.forEach((function (e, i) { a.push.apply(a, l(t._findMatches({ key: e, value: r[i], searcher: n }))) })), a.length && c.push({ idx: o, item: r, matches: a }) } })), c } }, { key: \"_findMatches\", value: function (e) { var t = e.key, n = e.value, r = e.searcher; if (!k(n)) return []; var i = []; if (v(n)) n.forEach((function (e) { var n = e.v, o = e.i, c = e.n; if (k(n)) { var a = r.searchIn(n), s = a.isMatch, u = a.score, h = a.indices; s && i.push({ score: u, key: t, value: n, idx: o, norm: c, indices: h }) } })); else { var o = n.v, c = n.n, a = r.searchIn(o), s = a.isMatch, u = a.score, h = a.indices; s && i.push({ score: u, key: t, value: o, norm: c, indices: h }) } return i } }]), e }(); return ve.version = \"6.4.6\", ve.createIndex = $, ve.parseIndex = function (e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.getFn, r = void 0 === n ? A.getFn : n, i = e.keys, o = e.records, c = new E({ getFn: r }); return c.setKeys(i), c.setIndexRecords(o), c }, ve.config = A, function () { ee.push.apply(ee, arguments) }(Z), ve }, \"object\" == typeof exports && \"undefined\" != typeof module ? module.exports = t() : \"function\" == typeof define && define.amd ? define(t) : (e = e || self).Fuse = t();\n", "/*\n * Some notes on how this works...\n *\n * paletteData is passed into the constructor and is the initial list of items\n * these are TurboAdminMenuItem objects\n *\n * At any point, buildPaletteItems() can be called to turn the paletteData\n * into an array of \"li\" nodes.\n *\n * updatePaletteItems inserts the paletteItems into the \"ul\" list and sets the\n * selectedElement\n *\n * The selectedItem is always one of the paletteItems\n *\n * paletteSearch rebuilds the paletteItems from the paletteData using\n * buildPaletteItems, and then filters the list with FuseJS\n */\n\nimport Fuse from './fuse-6.4.6.js';\nimport TurboAdminMenuItem from './class-turbo-admin-menu-item';\nimport ContentApi from './class-content-api.js';\n\nexport default class TurboAdminPalette {\n\n\tconstructor(paletteData, options) {\n\n\t\tconsole.log('Initialising TurboAdmin');\n\n        this.options = options;\n\n        /** @type {HTMLDivElement} */\n        this.paletteElement      = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-container'));\n        /** @type {HTMLDivElement} */\n        this.paletteInnerElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette'));\n\t\t/** @type {HTMLInputElement} */\n        this.paletteInputElement = /** @type {HTMLInputElement} */ (document.getElementById('ta-command-palette-input'));\n\t\t/** @type {HTMLUListElement} */\n        this.paletteItemsElement = /** @type {HTMLUListElement} */ (document.getElementById('ta-command-palette-items'));\n\n\t\t// Get palette data\n\t\tthis.paletteData = paletteData;\n\n        // Get post type data from API\n        this.postTypes = [];\n        this.fetchPostTypes();\n\n        // paletteItems is the list of 'li' elements used to build the palette\n        this.paletteItems = [];\n\n        // itemIndex is a \"cache\" of URLs used to check if we already\n        // have an item in the palette\n        this.itemIndex = {};\n\n        // Convert into LI elements\n        this.buildPaletteItems();\n\n\n\t\tthis.selectedItem = this.paletteItems[0];\n        this.openedSubMenu = null;\n        this.selectedSubItem = null;\n\n\t\t// Add them to the DOM\n\t\tthis.updatePaletteItems();\n\n        // Set state\n        this.navigating = false;\n        this.debounceTimeout;\n\n\t\tthis.paletteFuseOptions = [];\n\t\tthis.paletteFuse = null;\n\n\t\tif (typeof (Fuse) !== 'function') {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.paletteFuseOptions = {\n\t\t\tkeys: ['innerText'],\n\t\t}\n\n\t\tthis.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);\n\n\t\tdocument.addEventListener('keydown', e => this.handleGlobalKey(e));\n\n\t\tthis.paletteElement.addEventListener('click', e => {\n\t\t\tthis.checkForPaletteItemClick(e);\n            this.checkForClickToClose(e);\n\t\t});\n\n        this.paletteItemsElement.addEventListener('mouseover', e => {\n            this.setHoveredItem(e.target);\n        });\n\t}\n\n    htmlDecode(input) {\n        var doc = new DOMParser().parseFromString(input, \"text/html\");\n        return doc.documentElement.textContent;\n    }\n\n    isMac() {\n        return navigator.platform.startsWith('Mac');\n    }\n\n    metaPressed(e) {\n        return this.isMac() ? e.metaKey : e.ctrlKey;\n    }\n\n    fetchPostTypes() {\n        if (! globalThis.contentApi.active) {\n            this.postTypes = [];\n            return;\n        }\n\n        globalThis.contentApi.get('types').then(\n            response => {\n                response.json().then(\n                    types => {\n                        this.postTypes = types;\n                    }\n                );\n            }\n        );\n    }\n\n\tbuildPaletteItems() {\n        this.paletteItems = [];\n        this.itemIndex = {};\n\n\t\tthis.paletteData.forEach(item => {\n\t\t\tconst li = document.createElement('li');\n\t\t\tconst a = document.createElement('a');\n\t\t\tli.appendChild(a);\n\t\t\ta.href = item.action;\n\t\t\tlet title = item.title;\n\t\t\tif (item.parentTitle) {\n\t\t\t\ttitle = item.parentTitle + \": \" + title;\n\t\t\t}\n\t\t\ta.innerHTML = title;\n            this.addPaletteListItem(li);\n\t\t});\n\t}\n\n    // This takes a 'li' element and adds it to the paletteItems.\n    // It also updates any caches and stuff.\n    addPaletteListItem(listItem) {\n        this.paletteItems.push(listItem);\n\n        const link = listItem.querySelector('a');\n        if (link) {\n            this.itemIndex[link.href] = 1;\n        }\n    }\n\n    contentItemExists(url) {\n        return Boolean(this.itemIndex[url]);\n    }\n\n    injectContentItems(contentItems) {\n        console.log('Injecting items');\n\n        // We'll need this in the loop below.\n        const profileLinkElem = document.getElementById('wp-admin-bar-edit-profile');\n        let profileLink = null;\n        if (profileLinkElem) {\n            profileLink = profileLinkElem.querySelector('a').href;\n        }\n\n        // TODO: Can we not do this on every content item inject?\n        // Check for presence of Oxygen Page builder\n        /** @type {HTMLElement|string|Number} */\n        let oxygenLinkElem = document.getElementById('toplevel_page_ct_dashboard_page');\n        // Also check for a menu bar item\n        if (! oxygenLinkElem) {\n            oxygenLinkElem = document.getElementById('wp-admin-bar-oxygen_admin_bar_menu');\n        }\n        // Check to see if Oxygen link is cached\n        if (! oxygenLinkElem) {\n            oxygenLinkElem = Number(window.localStorage.getItem('ta-has-oxygen-builder'));\n        }\n        // Save Oxygen builder status\n        window.localStorage.setItem('ta-has-oxygen-builder', Boolean(oxygenLinkElem) ? '1' : '0' );\n\n        if (contentItems.length > 0) {\n            contentItems.forEach(item => {\n                const itemTitle = item.title;\n                // const itemTitle = item.title.rendered;\n                const itemType = item.subtype;\n                const itemUrl = item.url;\n\n                // console.log('Adding item: ' + itemTitle);\n\n                // // Check if item already exists\n                if (this.contentItemExists(itemUrl)) {\n                    console.log('Not adding duplicate');\n                    return;\n                }\n\n                const itemTypeName = this.postTypes[itemType] ? this.postTypes[itemType].name : itemType;\n                const title = `${itemTitle} (${itemTypeName})`;\n\n                const li = document.createElement('li');\n                const a = document.createElement('a');\n                const subMenu = document.createElement('div');\n                const subMenuTitle = document.createElement('div');\n                const subMenuItems = document.createElement('ul');\n                subMenu.classList.add('ta-submenu');\n                subMenuTitle.classList.add('ta-submenu-title');\n\n                subMenuTitle.textContent = this.htmlDecode(itemTitle);\n                subMenuItems.classList.add('ta-submenu-items');\n                subMenu.appendChild(subMenuTitle);\n                subMenu.appendChild(subMenuItems);\n\n                const subMenuItem1 = document.createElement('li');\n                const subMenuLink1 = document.createElement('a');\n                subMenuLink1.innerText = \"View\";\n                subMenuLink1.href = itemUrl;\n                subMenuItem1.appendChild(subMenuLink1);\n                subMenuItems.appendChild(subMenuItem1);\n\n                if (profileLink) {\n                    // Need to get edit URL. This seems like the best way for now.\n                    const editLink = profileLink.replace('profile.php', `post.php?post=${item.id}&action=edit`);\n\n                    const subMenuItem2 = document.createElement('li');\n                    const subMenuLink2 = document.createElement('a');\n                    subMenuLink2.innerText = \"Edit\";\n                    subMenuLink2.href = editLink;\n                    subMenuItem2.appendChild(subMenuLink2);\n                    subMenuItems.appendChild(subMenuItem2);\n                }\n\n                if (oxygenLinkElem) {\n                    // Oxygen Edit Links are like: https://example.com.com/?page_id=26&ct_builder=true&ct_inner=true\n                    const oxygenLink = globalThis.taWp.home + `?page_id=${item.id}&ct_builder=true&ct_inner=true`;\n\n                    const subMenuItem3 = document.createElement('li');\n                    const subMenuLink3 = document.createElement('a');\n                    subMenuLink3.innerText = \"Edit with Oxygen\";\n                    subMenuLink3.href = oxygenLink;\n                    subMenuItem3.appendChild(subMenuLink3);\n                    subMenuItems.appendChild(subMenuItem3);\n                }\n\n                const subMenuItem3 = document.createElement('li');\n                const subMenuLink3 = document.createElement('a');\n                subMenuLink3.innerText = \"Copy link\";\n                // Because this is an href we're setting it gets URI encoded!\n                subMenuLink3.href = itemUrl;\n                subMenuLink3.setAttribute('data-action', 'clipboard');\n                subMenuItem3.appendChild(subMenuLink3);\n                subMenuItems.appendChild(subMenuItem3);\n\n\n                li.classList.add('ta-has-child-menu');\n\n                li.appendChild(a);\n                li.appendChild(subMenu);\n\n                a.href = itemUrl;\n                a.innerHTML = title;\n                this.addPaletteListItem(li);\n            })\n        }\n\n        // Reset the search to work on the new items\n        this.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);\n        this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map(i => i.item);\n\n        this.updatePaletteItems();\n    }\n\n\t/**\n     * Handle global keypresses (at document level). Note that other key presses\n     * are handled by paletteActions()\n     *\n     * @param {KeyboardEvent} e\n     */\n    async handleGlobalKey(e) {\n\t\tif (this.shortcutKeysPressed(e)) {\n            e.preventDefault();\n            e.stopPropagation();\n\t\t\tif (this.paletteShown()) {\n\t\t\t\tthis.hidePalette();\n\t\t\t} else {\n\t\t\t\tthis.showPalette();\n\t\t\t}\n\t\t}\n\n\t\tif (e.code === 'Escape' && this.paletteShown()) {\n\t\t\tif (this.isSubMenuOpen()){\n                this.closeSubMenu();\n            } else {\n                this.hidePalette();\n            }\n\t\t}\n\n        if (this.paletteShown()) {\n            await this.paletteActions(e);\n\t\t}\n\t}\n\n\tshortcutKeysPressed(keyEvent) {\n        // The reduce here works through all the different possible key combos\n        // (more than one can be specified in options)\n\t\tconst keysPressed = this.options.shortcutKeys.reduce(\n\t\t\t(keyPressed, combo) => {\n\t\t\t\tif (keyPressed) {\n\t\t\t\t\treturn keyPressed;\n\t\t\t\t}\n                return ((!navigator.platform.startsWith('Mac')) || (combo.meta === keyEvent.metaKey))\n                    && (combo.alt === keyEvent.altKey)\n                    && (combo.shift === keyEvent.shiftKey)\n                    && (combo.ctrl === keyEvent.ctrlKey)\n                    && (\n                        keyEvent.code === 'Key' + combo.key.toUpperCase()\n                        || ( combo.key === ' ' && keyEvent.code.toUpperCase() === 'SPACE' )\n                    );\n            }, false);\n\t\treturn keysPressed;\n\t}\n\n    async debouncedPaletteSearchAndUpdate() {\n        // If search string is not long enough for content search, then\n        // run without debounce.\n        if (\n            ( this.paletteInputElement.value !== '' && this.paletteInputElement.value.length <= 2)\n            || this.postTypes === [] ) {\n            this.debounceTimeout = null;\n            await this.paletteSearchAndUpdate();\n            return;\n        }\n        // If timer is null, reset it to 500ms and run your functions.\n        // Otherwise, wait until timer is cleared\n        if (!this.debounceTimeout) {\n            this.debounceTimeout = setTimeout(async function () {\n                // Reset timeout\n                this.debounceTimeout = null;\n\n                // Run the search function\n                await this.paletteSearchAndUpdate();\n            }.bind(this), 750);\n        }\n    }\n\n\t/**\n     * Handle (non-global) keypresses on the palette\n     *\n     * @param {KeyboardEvent} e\n     * @returns {Promise}\n     */\n    async paletteActions(e) {\n\t\tif (e.code === 'ArrowDown' && this.paletteShown()) {\n\t\t\te.preventDefault();\n\t\t\tthis.moveDown();\n\t\t\treturn;\n\t\t}\n\t\tif (e.code === 'ArrowUp' && this.paletteShown()) {\n\t\t\te.preventDefault();\n\t\t\tthis.moveUp();\n\t\t\treturn;\n\t\t}\n\t\tif (e.code === 'Enter' && this.paletteShown()) {\n            this.doAction(this.metaPressed(e));\n            return;\n\t\t}\n        if (this.isSubMenuOpen()) {\n            return;\n        }\n\t\tawait this.debouncedPaletteSearchAndUpdate();\n\t}\n\n\tshowPalette() {\n\t\tthis.paletteInputElement.value = '';\n        this.paletteItemsElement.scrollTop = 0;\n\t\tthis.paletteElement?.classList.add('active');\n\t\tthis.paletteInputElement?.focus();\n\t}\n\n\thidePalette() {\n        this.navigating = false;\n\t\tthis.paletteElement?.classList.remove('active');\n        this.paletteInputElement.value = '';\n        this.paletteInputElement.blur();\n        if (this.isSubMenuOpen()) {\n            this.closeSubMenu();\n        }\n\t}\n\n\tpaletteShown() {\n\t\treturn this.paletteElement?.classList.contains('active');\n\t}\n\n    checkForPaletteItemClick(e) {\n        if (e.target.tagName === 'A') {\n            e.preventDefault();\n            if (this.isSubMenuOpen()) {\n                this.selectedSubItem = e.target.closest('li');\n            } else {\n                this.selectedItem = e.target.closest('li');\n            }\n            this.setSelectedElement();\n\n            this.doAction(this.metaPressed(e));\n        }\n    }\n\n\tcheckForClickToClose(e) {\n\t\tif (e.target.id === this.paletteElement.id) {\n\t\t\tthis.hidePalette();\n\t\t}\n\t}\n\n\tsetSelectedElement() {\n        if (this.isSubMenuOpen()) {\n            this.paletteItemsElement?.querySelectorAll('.ta-submenu.active li.selected')?.forEach(e => e.classList.remove('selected'));\n            this.selectedSubItem.classList.add('selected');\n        } else {\n            this.paletteItemsElement?.querySelectorAll('li.selected')?.forEach(e => e.classList.remove('selected'));\n            if (this.selectedItem) {\n                this.selectedItem.classList.add('selected');\n                this.scrollList();\n            }\n        }\n\t}\n\n\tscrollList() {\n\t\t// Scrolling up\n\t\tif (this.selectedItem.offsetTop < this.paletteItemsElement.scrollTop) {\n\t\t\tthis.paletteItemsElement.scrollTop = this.selectedItem.offsetTop;\n\t\t}\n\t\t// Scrolling down\n\t\tif (this.selectedItem.offsetTop + this.selectedItem.offsetHeight > this.paletteItemsElement.offsetHeight + this.paletteItemsElement.scrollTop) {\n\t\t\tthis.paletteItemsElement.scrollTop = this.selectedItem.offsetTop + this.selectedItem.offsetHeight - this.paletteItemsElement.offsetHeight;\n\t\t}\n\t}\n\n    setHoveredItem(element) {\n        // Only do this for li's\n        if ('LI' === element.tagName) {\n            this.navigating = true;\n            if (this.isSubMenuOpen()) {\n                this.selectedSubItem = element;\n            } else {\n                this.selectedItem = element;\n            }\n            this.setSelectedElement();\n        }\n    }\n\n\tmoveDown() {\n        if (this.isSubMenuOpen()) {\n            const nextItem = this.selectedSubItem.nextElementSibling;\n            this.navigating = true;\n            if (nextItem) {\n                this.selectedSubItem = nextItem;\n                this.setSelectedElement();\n            }\n        } else {\n            const nextItem = this.selectedItem.nextElementSibling;\n            this.navigating = true;\n            if (nextItem) {\n                this.selectedItem = nextItem;\n                this.setSelectedElement();\n            }\n        }\n\t}\n\n\tmoveUp() {\n        if (this.isSubMenuOpen()) {\n            const prevItem = this.selectedSubItem.previousElementSibling;\n            this.navigating = true;\n            if (prevItem) {\n                this.selectedSubItem = prevItem;\n                this.setSelectedElement();\n            }\n        } else {\n            const prevItem = this.selectedItem.previousElementSibling;\n            this.navigating = true;\n            if (prevItem) {\n                this.selectedItem = prevItem;\n                this.setSelectedElement();\n            }\n        }\n    }\n\n    isSubMenuOpen() {\n        return null !== this.openedSubMenu;\n    }\n\n    openSubMenu(subMenuElement) {\n        // Set height in case main menu is smaller than sub menu\n        const subMenuHeight = subMenuElement.offsetHeight;\n        this.paletteItemsElement.style.minHeight = subMenuHeight + \"px\";\n        subMenuElement.classList.add('active');\n\n\n        this.selectedSubItem = subMenuElement.querySelector('li');\n        this.openedSubMenu = subMenuElement;\n        this.setSelectedElement();\n\n        this.paletteInputElement.disabled = true;\n        // Blur the input so that keys can continue to be captured\n        this.paletteInputElement.blur();\n    }\n\n    closeSubMenu(subMenuElement = null) {\n        if (null === subMenuElement) {\n            subMenuElement = document.querySelector('.ta-submenu.active');\n        }\n        subMenuElement.classList.remove('active');\n        this.selectedSubItem.classList.remove('active');\n        this.paletteItemsElement.style.minHeight = 'auto';\n        this.selectedSubItem = null;\n        this.openedSubMenu = null;\n        this.paletteInputElement.disabled = false;\n        this.paletteInputElement.focus();\n    }\n\n\tdoAction(metaPressed = false) {\n        if (this.isSubMenuOpen()) {\n            this.actOnItem(this.selectedSubItem, metaPressed);\n            return;\n        }\n        if (this.selectedItem.classList.contains('ta-has-child-menu')) {\n            const subMenu = this.selectedItem.querySelector('.ta-submenu');\n            this.openSubMenu(subMenu);\n            return;\n        }\n\n        this.actOnItem(this.selectedItem, metaPressed);\n    }\n\n    actOnItem(item, metaPressed) {\n        this.hidePalette();\n        const link = item.querySelector('a');\n        const url = link.href;\n\n        if ('clipboard' === link.dataset.action) {\n            navigator.clipboard.writeText(url);\n            return;\n        }\n\n        if (metaPressed) {\n            window.open(url, '_blank');\n        } else {\n            window.location = url;\n        }\n    }\n\n\tselectedItemDisplayed() {\n\t\treturn Array.from(this.paletteItemsElement.childNodes).includes(this.selectedItem);\n\t}\n\n\tasync paletteSearchAndUpdate() {\n\t\tawait this.paletteSearch();\n\t\tthis.updatePaletteItems();\n\t}\n\n\tasync paletteSearch() {\n        // Get the value...\n        // const response = await globalThis.contentApi.get('posts', { search: this.paletteInputElement.value, per_page: 100, status: ['publish', 'future', 'draft', 'pending', 'private'] });\n\n        this.buildPaletteItems();\n\n        if (this.paletteInputElement.value !== '') {\n            // Reset the search to work on the new items\n            this.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);\n            this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map(i => i.item);\n        }\n\n        // Content search - don't search everything!\n        if (globalThis.contentApi.active && this.postTypes !== [] && this.paletteInputElement.value.length > 2) {\n            this.paletteInnerElement.classList.add('loading');\n\n            globalThis.contentApi.getPosts(this.paletteInputElement.value)\n                .then(\n                    results => {\n                            this.injectContentItems(results);\n                            this.paletteInnerElement.classList.remove('loading');\n                    }\n                )\n        }\n\t}\n\n\tupdatePaletteItems() {\n\t\tconst newItems = document.createElement('ul');\n\t\tnewItems.id = 'ta-command-palette-items';\n\n\t\tthis.paletteItems.forEach(i => {\n\t\t\tnewItems.appendChild(i);\n\t\t})\n\n\t\tthis.paletteItemsElement.replaceChildren(...newItems.children);\n\n\t\tif (!this.navigating || !this.selectedItemDisplayed()) {\n\t\t\tthis.selectedItem = this.paletteItems[0];\n\t\t}\n\n\t\tthis.setSelectedElement();\n\t}\n\n}\n", "export default class TurboAdminMenuItem {\n\n\tconstructor(title, action, parentTitle, noCache = false) {\n\t\tthis.title = title;\n\t\tthis.action = action;\n\t\tthis.parentTitle = parentTitle;\n        this.noCache = noCache;\n\t}\n\n    sameAs(item) {\n        return item.title === this.title &&\n            item.action === this.action &&\n            item.parentTitle === this.parentTitle;\n    }\n}\n", "/**\n * This class is an abstraction of the browser extension storage API\n * (see https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage)\n * but that falls back to using regular localStorage if we're not in a\n * browser extension.\n *\n * This exists so that the same API can be used from both the browser\n * extension AND the plugin version of Turbo Admin.\n *\n * Note that for the extension, data saved is \"global\" to the extension\n * and is NOT site specific.\n */\nexport default class Storage {\n\n    /**\n     * Constructor - detects where code is running and sets the local\n     * store appropriately.\n     */\n    constructor() {\n        /** @type {null|storageStorageArea|WindowLocalStorage} */\n        this.store = null;\n\n        if ('undefined' === typeof (browser)) {\n            this.store = window.localStorage;\n        } else {\n            this.store = browser.storage.local;\n        }\n    }\n\n    /**\n     * Set/save extension data. Must be passed an object with key/value\n     * pairs.\n     *\n     * @param {Object} dataObject\n     */\n    async set(dataObject) {\n        if ('undefined' === typeof (browser)) {\n            const keys = Object.keys(dataObject);\n            keys.forEach(key => this.store.setItem(key, JSON.stringify(dataObject[key])));\n        } else {\n            await this.store.set(dataObject);\n        }\n    }\n\n    /**\n     * Get data from the extension's storage.\n     *\n     * Note that fetched data will be a object with the key as a\n     * property.\n     *\n     * @param {String} key\n     * @returns {Promise<Object>}\n     */\n    async get(key) {\n        if ('undefined' === typeof (browser)) {\n            let returnObj = {};\n            let item = this.store.getItem(key);\n            if (! item) {\n                return returnObj;\n            }\n            let itemObject = null;\n            try {\n                itemObject = JSON.parse(this.store.getItem(key));\n            } catch (e) {\n                itemObject = null;\n            }\n            returnObj[key] = itemObject;\n            return returnObj;\n        } else {\n            return await this.store.get(key);\n        }\n    }\n\n}\n", "import Storage from './class-storage.js';\n\nexport default class ContentApi {\n\n    constructor() {\n        // this.discoverApiRoot().then(e => null);\n        // console.log('Discovered API base: ', this.apiBase);\n        this.active = false;\n        this.store = new Storage();\n\n        // This is used to \"cache\" duplicate requests.\n        // It's an object because it will have search strings as keys\n        this.cache = {};\n    }\n\n    async discoverApiRoot() {\n        let wpApiSettings = null;\n        this.storageKey = 'wpApiSettings.' + globalThis.taWp.home;\n\n        // Could be in the wp-api-request-js-extra (on wp-admin side)\n        const wpApiSettingsScript = document.getElementById('wp-api-request-js-extra');\n        if (wpApiSettingsScript) {\n            const wpApiSettingsString = wpApiSettingsScript.innerHTML.match(/var\\s+wpApiSettings\\s+=\\s+(.+);/)[1];\n            const wpApiSettings = JSON.parse(wpApiSettingsString);\n            const objectToSave = {};\n            objectToSave[this.storageKey] = wpApiSettings;\n            await this.store.set(objectToSave);\n            this.apiRoot = wpApiSettings.root;\n            this.apiBase = this.apiRoot + wpApiSettings.versionString;\n            this.apiNonce = wpApiSettings.nonce;\n            // Clear the nonce if one is set and we're not logged in\n            this.maybeExpireNonce(wpApiSettings);\n            this.active = true;\n            return;\n        }\n\n        // Getting from extension storage returns a object with the key\n        // as the key. Which is weird.\n        wpApiSettings = await this.store.get(this.storageKey);\n        if (wpApiSettings\n            && Object.keys(wpApiSettings).length !== 0\n            && wpApiSettings[this.storageKey]\n            && 'object' === typeof(wpApiSettings[this.storageKey])) {\n            // Get the key'ed item out of the object\n            wpApiSettings = wpApiSettings[this.storageKey];\n            this.apiRoot = wpApiSettings.root;\n            this.apiBase = this.apiRoot + wpApiSettings.versionString;\n            this.apiNonce = wpApiSettings.nonce;\n            // Clear the nonce if one is set and we're not logged in\n            this.maybeExpireNonce(wpApiSettings);\n            this.active = true;\n            return;\n        }\n\n        // Could be in <link rel=\"https://api.w.org/\" href=\"https://something/wp-json/\">\n        if (globalThis.taWp.apiLinkUrl) {\n            this.apiRoot = globalThis.taWp.apiLinkUrl;\n            // Just guess this\n            this.apiBase = this.apiRoot + 'wp/v2/';\n            this.active = true;\n            return;\n        }\n    }\n\n    userLoggedIn() {\n        return document.body.classList.contains('logged-in') ||\n            document.body.classList.contains('wp-admin');\n    }\n\n    async maybeExpireNonce(wpApiSettings) {\n        if (wpApiSettings?.nonce && ! this.userLoggedIn()) {\n            // Clear apiSetting nonce\n            this.apiNonce = null;\n            wpApiSettings.nonce = null;\n            const objectToSave = {};\n            objectToSave[this.storageKey] = wpApiSettings;\n            await this.store.set(objectToSave);\n        }\n    }\n\n    makeParamString(data) {\n        const params = new URLSearchParams();\n\n        Object.keys(data).forEach(paramKey => {\n            // Handle arrays\n            if (Array.isArray(data[paramKey])) {\n                const arrayParamKey = paramKey + '[]';\n                data[paramKey].forEach( item => params.append(arrayParamKey, item));\n            } else {\n                params.append(paramKey, data[paramKey]);\n            }\n        });\n\n        return params.toString();\n    }\n\n    statuses() {\n        if (this.apiNonce) {\n            return [\"publish\", \"future\", \"draft\", \"pending\", \"private\"];\n        } else {\n            return [\"publish\"];\n        }\n    }\n\n    types() {\n        return globalThis.turboAdmin.turboAdminPalette.postTypes;\n    }\n\n    async getPosts(searchString) {\n        // Check the cache\n        if (undefined !== this.cache[searchString]) {\n            return this.cache[searchString];\n        }\n\n        // Fetch results\n        const response = await this.get(\n            // \"posts\",\n            \"search\",\n            {\n                search: searchString,\n                per_page: 100,\n                // status: this.statuses(),\n                type: 'post',\n                subtype: 'any'\n            }\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache[searchString] = result;\n\n        return result;\n    }\n\n    async get(path, data = {}) {\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n        }\n\n        // Add the nonce if there is one\n        if (this.apiNonce) {\n            data._wpnonce = this.apiNonce;\n        }\n\n        const params = this.makeParamString(data);\n\n        const response = await fetch(`${this.apiBase}${path}/?${params}`);\n\n        return response;\n    }\n\n}\n", "/**\n * It's impossible to change the setting to off, because the\n * extension's content script runs in a sandbox and can't access\n * the wp object. But we can just toggle the class every time.\n */\nexport default class TurboAdminWpBlockEditorFullscreenKill {\n\n    constructor() {\n\n        const attrObserver = new MutationObserver((mutations) => {\n            mutations.forEach(mu => {\n                // Check if we already killed fullscreen\n                // if (document.body.classList.contains('turbo-admin-killed-fullscreen')) {\n                //     return;\n                // }\n\n                if (mu.type !== \"attributes\" && mu.attributeName !== \"class\") {\n                    return;\n                }\n\n                if (mu.target.classList.contains('is-fullscreen-mode')) {\n                    this.killFullScreenEditor();\n                }\n            });\n        });\n\n        attrObserver.observe(document.body, { attributes: true });\n\n        // Also attempt a kill now in case it's already appeared.\n        this.killFullScreenEditor();\n    }\n\n    killFullScreenEditor() {\n        if (! document.body.classList.contains('is-fullscreen-mode')) {\n            return;\n        }\n\n        document.body.classList.remove('is-fullscreen-mode');\n        document.body.classList.add('turbo-admin-killed-fullscreen');\n\n        const newStyles = document.createElement('style');\n        newStyles.innerHTML = \"body.turbo-admin-killed-fullscreen .edit-post-fullscreen-mode-close { display: none; }\";\n        document.body.appendChild(newStyles);\n    }\n}\n", "/**\n *\n */\nexport default class TurboAdminWpBlockEditorWelcomeGuideKill {\n\n    constructor() {\n\n        const attrObserver = new MutationObserver((mutations) => {\n            mutations.forEach(mu => {\n                // Check if we already killed the modal\n                if (document.body.classList.contains('ta-killed-post-welcome-guide')) {\n                    return;\n                }\n\n                if (mu.type !== \"attributes\" && mu.attributeName !== \"class\") {\n                    return;\n                }\n\n                if (! mu.target.classList.contains('modal-open')) {\n                    return;\n                }\n\n                const welcomeGuide = document.querySelector('.edit-post-welcome-guide');\n                if (welcomeGuide) {\n                    this.killWelcomeGuide();\n                }\n            });\n        });\n\n        attrObserver.observe(document.body, { attributes: true });\n\n        // Also attempt a kill now in case it's already appeared.\n        this.killWelcomeGuide();\n    }\n\n    killWelcomeGuide() {\n        const welcomeGuide = document.querySelector('.edit-post-welcome-guide');\n        if (welcomeGuide) {\n            const closeButton = welcomeGuide.querySelector('.components-modal__header button');\n            if (closeButton) {\n                closeButton.click();\n                /*\n                 * Also add a class to body so we don't do it again - subsequent modals\n                 * will need to be shown as they will have been user-initiated.\n                 */\n                document.body.classList.add('ta-killed-post-welcome-guide');\n            }\n        }\n    }\n}\n", "export default class TurboAdminWpNotices {\n\n    // TODO: Handle empty IDS. Can we identify unique selectors?\n    // See spinup!\n    // Also need to only show move to panel if we can (i.e. if there's a way\n    // to identify it))\n    constructor(rememberedNoticeIds) {\n\n        // Bail if we aren't in the admin\n        if (! document.querySelector('body.wp-admin')) {\n            return;\n        }\n\n        /*\n        * These are the global notice selectors\n        */\n        this.noticeSelectors = [\n            '#wpbody-content > .notice',\n            '#wpbody-content > .wrap > .notice',\n            '#wpbody-content > .wrap > .updated',\n            '#gf_dashboard_message', // Gravity forms\n            '.jitm-banner', //\n            '.fs-notice', // I get this in Replyable\n            '#updraft-dashnotice', // Updraft backups\n            '.woocommerce-message', // WooCommerce\n            '#akismet_setup_prompt', // Akismet\n            '#wf-onboarding-plugin-header', // WordFence onboard\n            '.llar-notice-review' // Limit Login Attempts reloaded\n        ];\n\n        /*\n         * These selectors are allowed (unless explicitly denied)\n         */\n        this.allowedClasses = [\n            'notice-success',\n            'notice-error',\n            'notice-failure',\n            'updated',\n        ]\n\n        if (rememberedNoticeIds) {\n            this.rememberedNoticeIds = rememberedNoticeIds.length > 0 ? rememberedNoticeIds : [];\n        } else {\n            this.rememberedNoticeIds = [];\n        }\n\n        const toolbar = document.getElementById('wpadminbar');\n\n        if (!toolbar) {\n            return;\n        }\n\n        if (rememberedNoticeIds && rememberedNoticeIds.length > 0) {\n            rememberedNoticeIds.forEach(id => {\n                if ('string' === typeof(id) && id.length > 0) {\n                    this.noticeSelectors.push('#' + id);\n                }\n            });\n        }\n\nconsole.log('Notice Selectors', this.noticeSelectors);\n        const notices = document.querySelectorAll(this.noticeSelectors.join(','));\nconsole.log('Notices', notices);\n\n        // Add buttons to notices that can be moved\n        notices.forEach(notice => {\n            this.maybeAddIdToNotice(notice)\n\n            if (this.keepNotice(notice)) {\n                const rememberButton = document.createElement('button');\n                rememberButton.classList.add('ta-remember-notice-button');\n                rememberButton.innerText = 'Move to panel';\n\n                const forgetButton = document.createElement('button');\n                forgetButton.classList.add('ta-forget-notice-button');\n                forgetButton.innerText = 'Move to dashboard';\n\n                notice.classList.add('ta-added-pos-relative');\n\n                notice.appendChild(rememberButton);\n                notice.appendChild(forgetButton);\n\n                rememberButton.addEventListener('click', this.rememberNotice.bind(this), false, true);\n                forgetButton.addEventListener('click', this.forgetNotice.bind(this), false, true);\n            }\n        });\n\n        const noticesToHide = Array.from(notices).filter(notice => {\n            if (this.rememberedNoticeIds.includes(notice.id)) {\n                return true;\n            }\n\n            if (this.keepNotice(notice)) {\n                return false;\n            }\n\n            // Invisible\n            if (\n                notice.offsetHeight === 0 ||\n                notice.offsetWidth === 0\n            ) {\n                return false;\n            }\n\n            return true;\n        })\n\n        console.log('Notices to hide', noticesToHide)\n\n        /**\n         * Build the notices wrapper\n         */\n        /** @type {HTMLDivElement} */\n        const noticesLinkWrapper = document.createElement('div');\n        noticesLinkWrapper.id = 'ta-notices-link-wrap';\n        noticesLinkWrapper.classList.add('hide-if-no-js', 'screen-meta-toggle');\n        noticesLinkWrapper.style.margin='0 0 0 6px';\n        noticesLinkWrapper.style.float='left';\n        if (noticesToHide.length === 0) {\n            noticesLinkWrapper.style.display='none';\n        }\n\n        /**\n         * Add button\n         */\n        /** @type {HTMLButtonElement} */\n        const noticesButton = document.createElement('button');\n        noticesButton.type='button';\n        noticesButton.id='ta-notices-link';\n        noticesButton.classList.add('button', 'show-settings');\n        noticesButton.innerHTML='Notices <span id=\"ta-notice-count\">' + noticesToHide.length + '</span>';\n        noticesButton.setAttribute('aria-controls', 'ta-notices-wrap');\n\n        // This should replicate the functionality from wp-admin/js/common.js\n        // as closely as possible. But note that we can't access the common.js\n        // functions.\n        noticesButton.addEventListener('click', this.toggleNoticesPanel.bind(this), false);\n\n        /**\n         * Add button to the link wrapper\n         */\n        noticesLinkWrapper.appendChild(noticesButton);\n\n        /**\n         * Add the link wrapper to the screen-meta-links section\n         */\n        const screenMetaLinks = document.getElementById('screen-meta-links');\n        screenMetaLinks.appendChild(noticesLinkWrapper);\n\n        /**\n         * Build the panel\n         */\n        const noticesPanel = document.createElement('div');\n\n        noticesPanel.id='ta-notices-wrap';\n        noticesPanel.style.display='none';\n        noticesPanel.dataset.open='no';\n\n        const noticesPanelInner = document.createElement('div');\n        noticesPanelInner.id = 'ta-notices-panel-inner';\n\n        noticesToHide.forEach(notice => {\n            // Add 'inline' class otherwise WordPress might move them around!\n            notice.classList.add('inline');\n            // See Toolbelt's implementation: https://github.com/BinaryMoon/wp-toolbelt/blob/dev/modules/tidy-notifications/src/js/script.js\n            noticesPanelInner.append(notice);\n        });\n\n        /**\n         * Add wrap to the meta area\n         */\n        noticesPanel.appendChild(noticesPanelInner);\n        const screenMeta = document.getElementById('screen-meta');\n        screenMeta.appendChild(noticesPanel);\n\n        // Set up events on the new screen-meta item\n        // if (window.screenMeta) {\n        //     window.screenMeta.init();\n        // }\n    }\n\n    // Does the allowedClasses list say that this notice should be shown?\n    keepNotice(noticeElem) {\n        return this.allowedClasses.reduce( (found, current) => {\n            return found || noticeElem.classList.contains(current)\n        }, false);\n    }\n\n    rememberNotice(ev) {\n        const noticesLinkWrap = document.getElementById('ta-notices-link-wrap');\n        const panel = document.getElementById('wp-admin-bar-ta-notices');\n        const panelInner = document.getElementById('ta-notices-panel-inner');\n        const countElem = document.getElementById('ta-notice-count');\n        const count = parseInt(countElem.innerText, 10);\n        const notice = ev.target.closest(this.noticeSelectors.join(','));\n        const noticeId = notice.id;\n        console.log(`Remembering ${noticeId}`);\n        panelInner.appendChild(notice);\n        if (count === 0) {\n            noticesLinkWrap.style.display = 'block';\n        }\n\n        this.updateScreenMetaHeight();\n\n        countElem.innerText = parseInt(countElem.innerText, 10) + 1;\n\n        this.saveRememberedNotice(noticeId);\n    }\n\n    saveRememberedNotice(noticeId) {\n        this.rememberedNoticeIds.push(noticeId);\n\n        if ('object' === typeof(browser)) {\n            browser.runtime.sendMessage({\n                'action': 'rememberNotice',\n                'noticeId': noticeId,\n            });\n        } else {\n            window.localStorage.setItem('rememberedNoticeIds', JSON.stringify(this.rememberedNoticeIds));\n        }\n    }\n\n    forgetNotice(ev) {\n        const noticesLinkWrap = document.getElementById('ta-notices-link-wrap');\n        const panelInner = document.getElementById('ta-notices-panel-inner');\n        const countElem = document.getElementById('ta-notice-count');\n        const count = parseInt(countElem.innerText, 10);\n        const notice = ev.target.closest(this.noticeSelectors.join(','));\n        const noticeId = notice.id;\n        console.log(`Forgetting ${noticeId}`);\n\n        notice.remove();\n\n        const message = document.createElement('div');\n        const p = document.createElement('p');\n        message.classList.add('notice', 'ta-forget-notice-message');\n        p.textContent = 'Notice will be back in dashboard on next page load';\n        message.appendChild(p);\n        panelInner.appendChild(message);\n\n        this.updateScreenMetaHeight();\n\n        // I was going to to this, but we need to keep the notice about\n        // where the notice has gone.\n        // if (count === 1) {\n        //     noticesLinkWrap.style.display = 'none';\n        // }\n\n        countElem.innerText = (count - 1).toString();\n        this.saveForgottenNotice(noticeId);\n    }\n\n    saveForgottenNotice(noticeId) {\n        this.rememberedNoticeIds.push(noticeId);\n\n        if ('object' === typeof(browser)) {\n            browser.runtime.sendMessage({\n                'action': 'rememberNotice',\n                'noticeId': noticeId,\n            });\n        } else {\n            this.rememberedNoticeIds = this.rememberedNoticeIds.filter( id => id !== noticeId );\n            window.localStorage.setItem('rememberedNoticeIds', JSON.stringify(this.rememberedNoticeIds));\n        }\n    }\n\n    /*\n     * For notices without IDs we'll see if we can add an ID that's a hash of their classlist\n     */\n    maybeAddIdToNotice(notice) {\n        if (notice.id && notice.id !== '' && notice.id !=='message') {\n            return;\n        }\n\n        const classes = notice.classList;\n        notice.id = Array.from(notice.classList).join('-');\n    }\n\n    /**\n     * Detect if WordPress has already applied event handlers to our new screen meta button.\n     *\n     * If it has then WordPress/backbone.js will handle the animation and we won't have to.\n     *\n     * @returns {boolean}\n     */\n    wordpressScreenMetaEventsExist() {\n        return 'object' === typeof(window.screenMeta) && window.screenMeta.toggles.filter('#ta-notices-link').length > 0;\n    }\n\n    updateScreenMetaHeight() {\n        // Don't do this if we're relying on backbone's animation\n        if (this.wordpressScreenMetaEventsExist()) {\n            return;\n        }\n\n        const screenMeta = document.getElementById('screen-meta');\n        const noticesPanel = document.getElementById('ta-notices-wrap');\n        const height = noticesPanel.offsetHeight;\n        screenMeta.style.maxHeight = height.toString(10) + 'px';\n    }\n\n    toggleNoticesPanel(ev) {\n        // We may be in the plugin in which case we don't want to run our handler if there's\n        // a backbone handler on the button.\n        if (this.wordpressScreenMetaEventsExist()) {\n            return;\n        }\n        // Otherwise we mimic the swipe down animation.\n        const animationSeconds = 0.3;\n        const screenMeta = document.getElementById('screen-meta');\n        const noticesPanel = document.getElementById('ta-notices-wrap');\n        if (noticesPanel.dataset.open === 'no') {\n            this.toggleOtherScreenMetaTabs();\n            // Don't ask... just DON'T ask!\n            noticesPanel.dataset.open = 'yes';\n            screenMeta.style.transition = `max-height ${animationSeconds.toString(10)}s`;\n            screenMeta.style.maxHeight = '0';\n            screenMeta.style.overflow = 'hidden';\n            screenMeta.style.display = 'block';\n            noticesPanel.style.display = 'block';\n            const height = noticesPanel.offsetHeight;\n            screenMeta.style.maxHeight = height.toString(10) + 'px';\n            // setTimeout(() => {\n            //     // Nothing to do here.\n            // }, animationSeconds * 1000);\n        } else {\n            noticesPanel.dataset.open = 'no';\n            const height = noticesPanel.offsetHeight;\n            screenMeta.style.maxHeight = '0';\n            setTimeout(() => {\n                noticesPanel.style.display = '';\n                screenMeta.style.display = '';\n                screenMeta.style.transition = '';\n                screenMeta.style.overflow = '';\n                screenMeta.style.maxHeight = '';\n                this.toggleOtherScreenMetaTabs();\n            }, animationSeconds * 1000);\n        }\n\n    }\n\n    toggleOtherScreenMetaTabs() {\n        const otherTabs = document.querySelectorAll('#screen-meta-links .screen-meta-toggle:not(#ta-notices-link-wrap)');\n        otherTabs.forEach( (tab) => {\n            if (tab.style.visibility === 'hidden') {\n                tab.style.visibility = '';\n            } else {\n                tab.style.visibility = 'hidden';\n            }\n        } );\n    }\n}\n", "export default class ListTableShortcuts {\n\n    constructor() {\n        /**\n         * @type {ListTableShortcuts}\n         */\n        const me = this;\n\n        /**\n         * @type {null|HTMLElement}\n         */\n        this.currentRow = null;\n\n        /**\n         * @type {number}\n         */\n        this.currentRowIndex = 0;\n\n        /**\n         * @type {HTMLTableElement}\n         */\n        this.listTable = document.querySelector('.wp-list-table');\n\n        if (! this.listTable) {\n            return;\n        }\n\n        /**\n         * @type {NodeListOf<HTMLTableRowElement>}\n         */\n        this.tableRows = this.listTable.querySelectorAll('tbody#the-list > tr');\n\n        document.addEventListener('keyup', e => this.handleKeyup(e));\n    }\n\n    /**\n     *\n     * @param {KeyboardEvent} ev\n     */\n    handleKeyup(ev) {\n        if (document.activeElement.tagName !== 'BODY') {\n            return;\n        }\n\n        if (ev.key === 'j') {\n            this.tableMoveDown();\n        } else if (ev.key === 'k') {\n            this.tableMoveUp();\n        } else if (ev.key.toLowerCase() === 'enter' && this.currentRow !== null) {\n            this.openTableRowItem();\n        }\n\n    }\n\n    tableMoveDown() {\n        this.preTableChange();\n\n        // Move down\n        if (this.currentRow === null) {\n            this.currentRowIndex = 0;\n        } else {\n            this.currentRowIndex++;\n        }\n        this.updateTable();\n    }\n\n    tableMoveUp() {\n        this.preTableChange();\n\n        if (this.currentRowIndex > 0) {\n            this.currentRowIndex--;\n            this.updateTable();\n        }\n    }\n\n    preTableChange() {\n        if (this.currentRow !== null) {\n            this.tableRows[this.currentRowIndex].classList.remove('ta-active-table-row');\n        }\n    }\n\n    updateTable() {\n        this.currentRow = this.tableRows[this.currentRowIndex];\n\n        if (! this.tableRows[this.currentRowIndex].classList.contains('ta-active-table-row')) {\n            this.tableRows[this.currentRowIndex].classList.add('ta-active-table-row');\n        }\n    }\n\n    openTableRowItem() {\n        console.log(this);\n        /** @type {HTMLAnchorElement} */\n        const link = this.currentRow.querySelector('a.row-title');\n        if (link) {\n            link.click();\n        }\n    }\n}\n", "export default class TurboAdminBarkeeper {\n\n    constructor(barkeeperState) {\n        // Bail if we aren't in the admin\n        if (! document.getElementById('wpadminbar')) {\n            return;\n        }\n\n        this.exclusionIds = [\n            'wp-admin-bar-menu-toggle',\n            'wp-admin-bar-wp-logo',\n            'wp-admin-bar-site-name',\n            'wp-admin-bar-updates',\n        ];\n\n        this.barkeeperState = barkeeperState;\n\n        this.root = document.getElementById('wp-admin-bar-root-default');\n        this.itemsToHide = document.querySelectorAll( '#wp-admin-bar-root-default > li');\n\n        Array.from(this.itemsToHide).forEach( element => {\n            if (this.exclusionIds.includes(element.id)) {\n                return;\n            }\n            element.classList.add('ta-barkeeper-collapsable');\n        });\n\n        if (this.barkeeperState === 'closed') {\n            this.root.classList.toggle('ta-barkeeper-closed');\n        }\n\n        // Add toggle\n        this.button = document.createElement('button');\n        this.button.id = 'ta-barkeeper-toggle';\n        this.button.innerText = '<';\n\n        this.button.addEventListener('click', e => {\n            this.root.classList.toggle('ta-barkeeper-closed');\n\n            this.barkeeperState = this.barkeeperState === 'open' ? 'closed' : 'open';\n\n            if ('object' === typeof(browser)) {\n                browser.runtime.sendMessage({\n                    'action': 'barkeeperSetState',\n                    'barkeeperState': this.barkeeperState,\n                });\n            } else {\n                window.localStorage.setItem('turboAdminBarkeeperState', this.barkeeperState);\n            }\n        });\n\n        this.root.insertAdjacentElement('afterend', this.button);\n    }\n\n}\n", "/*\n * This is the common Turbo Admin library.\n *\n * It's (currently) WordPress-specific, but can be loaded by\n * either the Extension OR the Plugin\n *\n * It takes an options object:\n *\n * options: {\n *   shortcutKeys: [\n *     // Array of shortcut key definitions, like:\n *     {\n *       {\n *         meta: false,\n *         alt: true,\n *         ctrl: true,\n *         shift: true,\n *         key: 'p'\n *       }\n *     }\n *   ],\n *   appendToElement {\n *     // Optional CSS selector to define what to append the palette to\n *     'body'\n *   },\n *   extraItems: [\n *     // Optional array of extra item configs used to generate new item objects\n *     {\n *       'detectType': 'url',\n *       'detectPattern': 'wp-login',\n *       'itemTitle': 'View/visit site',\n *       'itemUrlFunction': () => this.home\n *     },\n *   ],\n *   extraItemsRaw: [\n *     // Optional array of raw item objects to be added\n *     {\n *       'title': ,\n *       'action': ,\n *       'parentTitle': ,\n *     }\n *   ]\n * }\n */\nimport TurboAdminPalette from './class-turbo-admin-palette.js';\nimport TurboAdminMenuItem from './class-turbo-admin-menu-item.js';\nimport Acf from './class-acf.js';\nimport TurboAdminWpBlockEditorFullscreenKill from './class-turbo-admin-wp-block-editor-fullscreen-kill.js';\nimport TurboAdminWpBlockEditorWelcomeGuideKill from './class-turbo-admin-wp-block-editor-welcome-guide-kill.js';\nimport TurboAdminWpNotices from './class-turbo-admin-wp-notices.js';\nimport TurboAdminListTableShortcuts from './class-list-table-shortcuts.js';\nimport TurboAdminBarkeeper from './class-turbo-admin-barkeeper.js';\n\nexport default class TurboAdmin {\n\n    constructor(options) {\n        if (document.getElementById('ta-command-palette-container')) {\n            console.log('TurboAdmin already initialised - I won\\'t make a second copy!');\n            return;\n        }\n\n        this.options = options;\n    }\n\n    async init() {\n        // Grab the global Wp object instance\n        this.wp = globalThis.taWp;\n\n        this.menu = [];\n        // Check for saved menu when on front-end\n        if (! this.wp.isBackend) {\n            // Only use the cached items if the current URL matches the last site URL\n            // This handles changes of multi-site site!\n            // We ONLY need to do this on the front-end as the back-end will always\n            // refresh the menu.\n            if (! this.wp.siteChanged) {\n                // Get from localStorage\n                const savedMenu = window.localStorage.getItem('ta-palette-data');\n\n                if (null !== savedMenu) {\n                    // Check for .logged-in class on body\n                    if (document.body.classList.contains('logged-in')) {\n                        // If still logged in merge (?) the items\n                        this.menu = JSON.parse(savedMenu);\n                    }\n                }\n            }\n        } else {\n            // On the back end, get the WordPress dashboard menu items\n            this.menu = this.getMenu();\n        }\n\n        // Add other additional items\n        this.addAdditionalMenuItems();\n        // Add items passed in using extraItemsRaw\n        this.menu = this.menu.concat(this.options.extraItemsRaw ?? []);\n\n        // Add ACF items?\n        // TODO: Make this better. Possible ASYNC somehow?\n        // this.acf = new Acf();\n        // if (this.acf.isAcfInstalled()) {\n        //     const acfLinks = await this.acf.getFieldGroups()\n        //     // console.table(acfItems);\n        //     const acfMenuItems = acfLinks.map(\n        //         item => new TurboAdminMenuItem(\n        //             item.label + ' (ACF)',\n        //             item.link,\n        //             ''\n        //         )\n        //     );\n        //     this.menu = this.menu.concat(acfMenuItems);\n        // }\n\n        // Sort the menu\n        this.menu.sort((a, b) => (a.parentTitle + a.title).localeCompare(b.parentTitle + b.title));\n\n        // Filter out no-cache items and save to localStorage.\n        const itemsToSave = this.menu.filter(item => (! item.noCache));\n        window.localStorage.setItem('ta-palette-data', JSON.stringify(itemsToSave));\n\n        // Add palette markup to the DOM\n        this.addPalette();\n        // Initialise controls on the palette\n        this.turboAdminPalette = new TurboAdminPalette(this.menu, this.options);\n\n        if (true === this.options['block-editor-fullscreen-disable']) {\n            // Initialise fullscreen kill\n            this.turboAdminFullscreenKill = new TurboAdminWpBlockEditorFullscreenKill();\n        }\n\n        if (true === this.options['block-editor-welcome-screen-kill']) {\n            this.turboAdminWelcomeKill = new TurboAdminWpBlockEditorWelcomeGuideKill();\n        }\n\n        if (true === this.options['list-table-keyboard-shortcuts']) {\n            this.turboAdminListTableShortcuts = new TurboAdminListTableShortcuts();\n        }\n\n        if (true === this.options['barkeeper']) {\n            // In the plugin, barkeeper-state will be in... local storage(?)\n            if ('object' !== typeof(browser)) {\n                this.options['barkeeper-state'] = window.localStorage.getItem('turboAdminBarkeeperState');\n            }\n            this.turboAdminBarkeeper = new TurboAdminBarkeeper(this.options['barkeeper-state']);\n        }\n\n        // Add other things if we're logged in and have an API nonce\n        if (globalThis.contentApi.userLoggedIn()) {\n            // What shall we do?\n        }\n    }\n\n    getMenu() {\n        const items = [];\n        const menuTop = document.getElementById('adminmenu');\n        if (menuTop) {\n            const topDOMItems = menuTop.querySelectorAll('li.menu-top');\n            topDOMItems.forEach(el => {\n                const a = el.querySelector('a.menu-top');\n                const title = a.querySelector('.wp-menu-name').innerHTML;\n                const action = a.href;\n                const parentTitle = '';\n                const item = new TurboAdminMenuItem(title, action, parentTitle);\n                items.push(item);\n\n                const subMenu = el.querySelector('.wp-submenu');\n                if (!subMenu) {\n                    return;\n                }\n                const subItems = subMenu.querySelectorAll('li a');\n                if (!subItems) {\n                    return;\n                }\n                subItems.forEach(subEl => {\n                    const parentTitle = title;\n                    const childTitle = subEl.innerHTML;\n                    const childAction = subEl.href;\n                    const item = new TurboAdminMenuItem(childTitle, childAction, parentTitle);\n                    items.push(item);\n                })\n            });\n        }\n        return items;\n    }\n\n    addAdditionalMenuItems() {\n\n        /*\n         * I'd LOVE for this to be config driven\n         *\n         * [\n         *   {\n         *     'detectType': 'url',\n         *     'detectPattern': 'wp-login',\n         *     'itemTitle': 'View/visit site',\n         *     'itemUrlFunction': () => this.home\n         *   },\n         *   {\n         *     'detectType': 'dom',\n         *     'detectSelector': '#wpadminbar',\n         *     'itemTitle': 'Logout',\n         *     'itemUrlFunction': () => logoutUrl\n         *   }\n         *  Can we add actionTypes as well? To do clicks and navigates?\n         * ]\n         */\n\n        // Get passed-in extraItems\n        let extraItems = this.options.extraItems ?? [];\n\n        // Merge in defaults\n        extraItems = extraItems.concat(\n            [\n                {\n                    'detectType': 'dom',\n                    'detectSelector': 'body.wp-admin #wp-admin-bar-view-site a',\n                    'itemTitleFunction': () => 'View/visit site',\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-dashboard a',\n                    'itemTitleFunction': (element) => element.textContent,\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wpadminbar',\n                    'itemTitleFunction': () => 'Logout',\n                    'itemUrlFunction': () => document.getElementById('wp-admin-bar-logout')?.querySelector('a')?.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-edit a',\n                    'itemTitleFunction': (item) => item.textContent,\n                    'itemUrlFunction': (item) => item.href,\n                    'noCache': true,\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-view a',\n                    'itemTitleFunction': (item) => item.textContent,\n                    'itemUrlFunction': (item) => item.href,\n                    'noCache': true,\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-new-content .ab-submenu a',\n                    'itemTitleFunction': (item) => 'New ' + item.textContent,\n                    'itemUrlFunction': (item) => item.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-customize a',\n                    'itemTitleFunction': (item) => item.textContent,\n                    'itemUrlFunction': (item) => item.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelectorNone': '#wpadminbar, #loginform',\n                    'itemTitleFunction': () => \"Log in\",\n                    'itemUrlFunction': () => {\n                        if (globalThis.taWp.home) {\n                            return globalThis.taWp.siteUrl;\n                        }\n                        // Try getting wp-admin\n                        return 'javascript:alert(\\'Sorry, could not detect login URL.\\')';\n                    }\n                },\n                // This is on the login screen\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#backtoblog a',\n                    'itemTitleFunction': () => \"View/visit site\",\n                    'itemUrlFunction': (element) => element.href\n                },\n                // Multisite items\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-network-admin > a',\n                    'itemTitleFunction': () => \"Network Admin\",\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-network-admin .ab-submenu a',\n                    'itemTitleFunction': (element) => 'Network Admin: ' + element.textContent,\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-my-sites-list .ab-submenu a',\n                    'itemTitleFunction': (element) => \"Sites: \" + element.closest('.menupop').querySelector('a').innerText + ' - ' + element.innerText,\n                    'itemUrlFunction': (element) => element.href\n                },\n                // Oxygen builder items\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#ct-edit-template-builder',\n                    'itemTitleFunction': () => 'Edit with Oxygen',\n                    'itemUrlFunction': (element) => element.href,\n                    'noCache': true\n                },\n                // It's worth noting that the Oxygen Builder doesn't use a /wp-admin URL\n                // and so kinda appears to Turbo Admin to be a \"front-end\" page and it\n                // doesn't refresh the menu items.\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '.oxygen-back-to-wp-menu .oxygen-toolbar-button-dropdown a:not(:last-of-type)',\n                    'itemTitleFunction': (element) => 'Back to WP: ' + element.textContent,\n                    'itemUrlFunction': (element) => {\n                        if (element.href) {\n                            return element.href;\n                        } else {\n                            let url = new URL(window.location.href);\n                            return url.origin + url.pathname;\n                        }\n                    },\n                    'noCache': true\n                }\n            ]\n        );\n\n        extraItems.forEach(item => {\n            let detected = false;\n            let elements = null;\n            if (item.detectType === 'url') {\n                detected = Boolean(window.location.href.includes(item.detectPattern));\n            } else if (item.detectType === 'dom') {\n                if (item.detectSelector) {\n                    elements = document.querySelectorAll(item.detectSelector);\n                    detected = Boolean(elements);\n                } else if (item.detectSelectorNone) {\n                    elements = document.querySelectorAll(item.detectSelectorNone);\n                    detected = elements.length === 0;\n                    // Need to pass SOMETHING to the loop below\n                    elements = document.querySelectorAll('body');\n                }\n            }\n            if (!detected) {\n                return;\n            }\n\n            elements.forEach(element => {\n                const newItem = new TurboAdminMenuItem(item.itemTitleFunction(element), item.itemUrlFunction(element), '', item?.noCache);\n                // Might already have one so check.\n                if (this.menu.some(menuItem => {\n                    // This must be newItem.sameAs, not menuItem.sameAs because the menuItem\n                    // may have been loaded from saved menu and may not actually be an instance\n                    // of a TurboAdminMenuItem.\n                    return newItem.sameAs(menuItem)\n                } )) {\n                    return;\n                }\n                // We don't already have one. So add it.\n                this.menu.push(newItem);\n            });\n        })\n    }\n\n    addPalette() {\n        const container = document.createElement('div');\n        container.id = 'ta-command-palette-container';\n        // Palette\n        const palette = document.createElement('div');\n        palette.id = 'ta-command-palette';\n        // Input field\n        const input = document.createElement('input');\n        input.id = \"ta-command-palette-input\";\n        input.name = \"ta-command-palette-input\";\n        input.type = \"text\";\n        // Set this to stop stuff trying to fill it.\n        input.setAttribute('autocomplete', 'off');\n        // List\n        const list = document.createElement('ul');\n        list.id = \"ta-command-palette-items\";\n        // Join it all up\n        container.appendChild(palette);\n        palette.appendChild(input);\n        palette.appendChild(list);\n\n        if (document.getElementById('wpadminbar') && this.options['admin-bar-search'] === true) {\n            const paletteLi = document.createElement('li');\n            paletteLi.appendChild(container);\n            const adminBar = document.getElementById('wp-admin-bar-top-secondary');\n            adminBar.appendChild(paletteLi);\n\n            // Add focus handler\n            input.addEventListener('focus', e => this.turboAdminPalette.showPalette());\n\n            // Add placeholder\n            const placeholder = document.createElement('div');\n            placeholder.id = 'ta-shortcut-key-placeholder';\n            placeholder.innerText = this.buildShortcutKeysString();\n            placeholder.addEventListener('click', e => input.focus());\n\n            palette.insertBefore( placeholder, list );\n        } else {\n            // Container\n            document.querySelector(this.options.appendToElement ?? 'body').appendChild(container);\n        }\n    }\n\n    buildShortcutKeysString () {\n        let keysString = '';\n        let shortcut = this.options.shortcutKeys[0];\n\n        if ( shortcut.meta ) {\n            keysString += 'Cmd-';\n        }\n        if ( shortcut.ctrl ) {\n            keysString += 'Ctrl-';\n        }\n        if ( shortcut.alt ) {\n            keysString += 'Alt-';\n        }\n        if ( shortcut.shift ) {\n            keysString += 'Shift-';\n        }\n        keysString += shortcut.key.toUpperCase();\n        return keysString;\n    }\n\n}\n", "export default class Wp {\n\n    constructor() {\n\n        // Set home and siteUrl\n        this.siteUrl = '';\n        this.home = '';\n        this.loginUrl = '';\n        this.apiLinkUrl = '';\n    }\n\n    async completeInit() {\n        // Fetch previously loaded site URL\n        this.previousUrl = window.localStorage.getItem('ta-palette-data-site');\n\n        // Fetch previously-stored siteUrl and home\n        this.siteUrl = window.localStorage.getItem('ta-palette-data-siteurl');\n        this.home = window.localStorage.getItem('ta-palette-data-home');\n\n        /**\n         * Are we in the back-end?\n         */\n        this.isBackend = this.getIsBackend();\n\n        /**\n         * Figure out all the WP URLs\n         */\n        await this.getUrls();\n\n        /**\n         * Tells you if the best-guess site URL of the current page is different\n         * to that of the previously saved site URL.\n         */\n        this.siteChanged = this.home !== this.previousUrl;\n\n        // Save current site URL for next time\n        window.localStorage.setItem('ta-palette-data-site', this.home);\n    }\n\n    getIsBackend() {\n        return document.body.classList.contains('wp-admin');\n    }\n\n    /**\n     * Return the URL with a trailing slash if it didn't already have one.\n     *\n     * @param {String} url The URL to check\n     * @return {String}    The resulting URL\n     */\n    ensureTrailingSlash( url ) {\n        if (url.endsWith('/')) {\n            return url;\n        } else {\n            return url + '/';\n        }\n    }\n\n    /**\n     * Tests if a URL works and, if redirected, that the final URL contains a given\n     * string. Returns the final, redirected-to URL if the test passed, or false\n     * otherwise.\n     *\n     * @param {String} url                    The URL to test.\n     * @param {String} responseUrlMustContain The string to test against the final URL\n     * @returns {Promise<String|Boolean>}   The final URL or false.\n     */\n    async testUrl(url, responseUrlMustContain='') {\n\n        /** @type {RequestInit} */\n        const init = {\n            method: 'HEAD',\n            mode: 'cors',\n            cache: 'no-cache',\n            credentials: 'same-origin'\n        }\n\n        const response = await fetch(url, init);\n\n        if (response.redirected && !response.url.includes(responseUrlMustContain)) {\n            return false;\n        }\n\n        if ( ! response.ok ) {\n            return false;\n        }\n\n        return response.url;\n    }\n\n    async findWhichUrlWorks(urls, responseUrlMustContain='') {\n        let workingUrl = false;\n        let result;\n        // This has to be a for loop rather than reduce or forEach as separate\n        // async callbacks would be launched asynchronously.\n        for (let i=0; i<urls.length; i++) {\n            if (workingUrl) continue;\n            result = await this.testUrl(urls[i], responseUrlMustContain);\n            if (result !== false) {\n                workingUrl = result;\n            }\n        }\n        return workingUrl;\n    }\n\n    /**\n     *\n     * @param {String} homeUrl\n     */\n    async guessSiteUrlFromHome( homeUrl ) {\n        const homeWithSlash = this.ensureTrailingSlash(homeUrl);\n\n        // NOTE: Backed out of this until I can make it work async.\n        // Might not even be a good idea anyway.\n\n        // const possibleUrls = [\n        //     homeWithSlash + 'wp-admin/',\n        //     homeWithSlash + 'wp/wp-admin'\n        // ];\n        // return this.findWhichUrlWorks(possibleUrls, 'wp-admin');\n        return homeWithSlash + 'wp-admin/';\n    }\n\n    /**\n     *\n     * @param {String} homeUrl\n     */\n    async guessHome() {\n        const currentUrl = new URL(window.location);\n        const origin = this.ensureTrailingSlash(currentUrl.origin);\n\n        // NOTE: Backed out of this until I can make it work async.\n        // Might not even be a good idea anyway.\n\n        // const possibleUrls = [\n        //     origin\n        // ];\n        // return this.findWhichUrlWorks(possibleUrls, 'wp-admin');\n        return origin;\n    }\n\n    /**\n     *\n     * @param {String} siteUrl\n     * @returns {String}\n     */\n    guessHomeFromSiteUrl(siteUrl) {\n        // Not much we can do here.\n        return siteUrl.replace(/wp-admin\\/?/, '');\n    }\n\n    async getUrls() {\n        // See if we can actually find the URL for the API\n        /** @type {HTMLLinkElement|null} */\n        const apiLink = document.querySelector('link[rel=\"https://api.w.org/\"]');\n\n        if (apiLink) {\n            this.apiLinkUrl = apiLink.href;\n        }\n        // Figure out the siteurl and home - this is different on the front and back end\n        if (this.isBackend) {\n            // This is easy in the back end/Dashboard!\n            this.siteUrl = window.location.href.match(/(^.*wp-admin)/)[1];\n            this.home = document.getElementById('wp-admin-bar-site-name').querySelector('a').href;\n\n            // Always set the siteUrl and home as this is definitive\n            window.localStorage.setItem('ta-palette-data-siteurl', this.siteUrl);\n            window.localStorage.setItem('ta-palette-data-home', this.home);\n        } else if (! this.siteUrl || ! this.home) {\n\n            // If we're not in the backend then (in the extension at least) we\n            // could be on the front-end and not logged in, so check for an\n            // admin bar and grab from that if there is one.\n            if (document.getElementById('wpadminbar')) {\n                this.siteUrl = document.getElementById('wp-admin-bar-dashboard').querySelector('a').href;\n                // Try for the API link\n                if (this.apiLinkUrl) {\n                    if (this.apiLinkUrl.includes('/wp-json')) {\n                        this.home = this.apiLinkUrl.replace('wp-json/', '');\n                    }\n                    if (this.apiLinkUrl.includes('index.php?rest_route')) {\n                        this.home = this.apiLinkUrl.replace(/index.php\\?rest_route.*/, '');\n                    }\n                } else {\n                    // We know what the siteUrl is, so guess the home from the siteUrl\n                    this.home = this.guessHomeFromSiteUrl(this.siteUrl);\n                }\n\n            } else {\n                // Try for the API link\n                // TODO: This needs to be async so it doesn't hold things up.\n                if (this.apiLinkUrl) {\n                    if (this.apiLinkUrl.includes('/wp-json')) {\n                        this.home = this.apiLinkUrl.replace('wp-json/', '');\n                    }\n                    if (this.apiLinkUrl.includes('index.php?rest_route')) {\n                        this.home = this.apiLinkUrl.replace(/index.php\\?rest_route.*/, '');\n                    }\n                    // We (probably) know what the home link is now, so guess the wp-admin\n                    if (this.home) {\n                        this.siteUrl = await this.guessSiteUrlFromHome( this.home );\n                    } else {\n                        this.siteUrl = this.guessSiteUrl();\n                    }\n                } else {\n                    // We got nothing.\n                    this.home    = await this.guessHome();\n                    if (this.home) {\n                        this.siteUrl = await this.guessSiteUrlFromHome(this.home);\n                    }\n                }\n            }\n        }\n\n        // Always trim the / for comparisons\n        if (this.siteUrl) {\n            this.siteUrl = this.siteUrl.replace(/(.+)\\/$/, '$1');\n        }\n        if (this.home) {\n            this.home = this.home.replace(/(.+)\\/$/, '$1');\n        }\n\n        // console.log('siteUrl: ', this.siteUrl);\n        // console.log('home: ', this.home);\n    }\n\n}\n", "import TurboAdmin from './class-turbo-admin.js';\nimport ContentApi from './class-content-api.js';\nimport Wp from './class-wp.js';\nimport TurboAdminWpNotices from './class-turbo-admin-wp-notices.js';\n\nconst taStorageKey = 'turbo-admin-settings';\n\n// Note that in the extension, the globalThis is not the browser's global scope,\n// it is sandboxed. So we can't check across the plugin/extension boundary here.\nasync function taInit(settings) {\n\n    globalThis.turboAdmin = null;\n\n    // Handle empty settings\n    if (typeof(settings[taStorageKey]) === 'undefined') {\n        console.log('Weird. Turbo Admin could not find any settings');\n        return;\n    }\n\n    globalThis.turboAdminOptions = settings[taStorageKey];\n\n    // Get Wp stuff ready\n    globalThis.taWp = new Wp();\n\n    // Parts of this init are async.\n    await globalThis.taWp.completeInit();\n\n    console.log('Turbo Admin: WP is initialised');\n\n    // Get/set api settings\n    globalThis.contentApi = new ContentApi();\n    await globalThis.contentApi.discoverApiRoot();\n\n    console.log('Turbo Admin: Content API is initialised');\n\n    globalThis.turboAdmin = new TurboAdmin(globalThis.turboAdminOptions);\n\n    await globalThis.turboAdmin.init();\n\n    if (settings[taStorageKey]['hide-notices']) {\n        globalThis.turboAdminWpNotices = new TurboAdminWpNotices(settings[taStorageKey].rememberedNoticeIds);\n    }\n}\n\n/**\n * This is plugin-specific. It should not be present in the extension code.\n */\ndocument.addEventListener('DOMContentLoaded', async e => {\n\tglobalThis.turboAdminOptions = {};\n\tglobalThis.turboAdminOptions[taStorageKey] = {\n\t\t// wpTurboAdmin is set using wp_localize_script\n\t\tshortcutKeys: globalThis.wpTurboAdmin.keys,\n        // These don't apply to the plugin version\n        'block-editor-fullscreen-disable': false,\n        'block-editor-welcome-screen-kill': false,\n        // I don't think we'll do this in the plugin as the code would be SO different.\n        'live-dev-notice': false,\n        'list-table-keyboard-shortcuts': globalThis.wpTurboAdmin['listTableShortcuts'] === '1',\n        'hide-notices': globalThis.wpTurboAdmin['hideNotices'] === '1',\n        'rememberedNoticeIds': JSON.parse(window.localStorage.getItem('rememberedNoticeIds')) ?? new Array(),\n        'barkeeper': globalThis.wpTurboAdmin['barkeeper'] === '1',\n        'admin-bar-search': globalThis.wpTurboAdmin['adminBarSearch'] === '1',\n\t}\n\tawait taInit(globalThis.turboAdminOptions);\n});\n"],
    5   "mappings": "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",
     3  "sources": ["../src/fuse-6.4.6.js", "../src/class-turbo-admin-palette.js", "../src/types/class-turbo-admin-menu-item.js", "../src/class-storage.js", "../src/apis/class-content-api.js", "../src/types/class-submenu-item.js", "../src/types/class-content-item.js", "../src/types/class-search-mode.js", "../src/types/class-item-definition.js", "../src/types/class-turbo-admin-plugin.js", "../src/class-turbo-admin-wp-notices.js", "../src/class-list-table-shortcuts.js", "../src/plugins/class-turbo-admin-barkeeper.js", "../src/plugins/class-turbo-admin-content-search.js", "../src/plugins/class-turbo-admin-plugins.js", "../src/plugins/class-turbo-admin-users.js", "../src/plugins/class-turbo-admin-mu-sites.js", "../src/plugins/class-turbo-admin-oxygen-buillder.js", "../src/class-turbo-admin.js", "../src/class-wp.js", "../src/apis/class-woocommerce-api.js", "../src/apis/class-gravity-forms-api.js", "../src/main.js"],
     4  "sourcesContent": ["/**\n * Fuse.js v6.4.6 - Lightweight fuzzy-search (http://fusejs.io)\n *\n * Copyright (c) 2021 Kiro Risk (http://kiro.me)\n * All Rights Reserved. Apache Software License 2.0\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\nvar e, t; e = this, t = function () { \"use strict\"; function e(t) { return (e = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (e) { return typeof e } : function (e) { return e && \"function\" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? \"symbol\" : typeof e })(t) } function t(e, t) { if (!(e instanceof t)) throw new TypeError(\"Cannot call a class as a function\") } function n(e, t) { for (var n = 0; n < t.length; n++) { var r = t[n]; r.enumerable = r.enumerable || !1, r.configurable = !0, \"value\" in r && (r.writable = !0), Object.defineProperty(e, r.key, r) } } function r(e, t, r) { return t && n(e.prototype, t), r && n(e, r), e } function i(e, t, n) { return t in e ? Object.defineProperty(e, t, { value: n, enumerable: !0, configurable: !0, writable: !0 }) : e[t] = n, e } function o(e, t) { var n = Object.keys(e); if (Object.getOwnPropertySymbols) { var r = Object.getOwnPropertySymbols(e); t && (r = r.filter((function (t) { return Object.getOwnPropertyDescriptor(e, t).enumerable }))), n.push.apply(n, r) } return n } function c(e) { for (var t = 1; t < arguments.length; t++) { var n = null != arguments[t] ? arguments[t] : {}; t % 2 ? o(Object(n), !0).forEach((function (t) { i(e, t, n[t]) })) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(n)) : o(Object(n)).forEach((function (t) { Object.defineProperty(e, t, Object.getOwnPropertyDescriptor(n, t)) })) } return e } function a(e, t) { if (\"function\" != typeof t && null !== t) throw new TypeError(\"Super expression must either be null or a function\"); e.prototype = Object.create(t && t.prototype, { constructor: { value: e, writable: !0, configurable: !0 } }), t && u(e, t) } function s(e) { return (s = Object.setPrototypeOf ? Object.getPrototypeOf : function (e) { return e.__proto__ || Object.getPrototypeOf(e) })(e) } function u(e, t) { return (u = Object.setPrototypeOf || function (e, t) { return e.__proto__ = t, e })(e, t) } function h(e, t) { return !t || \"object\" != typeof t && \"function\" != typeof t ? function (e) { if (void 0 === e) throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); return e }(e) : t } function f(e) { var t = function () { if (\"undefined\" == typeof Reflect || !Reflect.construct) return !1; if (Reflect.construct.sham) return !1; if (\"function\" == typeof Proxy) return !0; try { return Date.prototype.toString.call(Reflect.construct(Date, [], (function () { }))), !0 } catch (e) { return !1 } }(); return function () { var n, r = s(e); if (t) { var i = s(this).constructor; n = Reflect.construct(r, arguments, i) } else n = r.apply(this, arguments); return h(this, n) } } function l(e) { return function (e) { if (Array.isArray(e)) return d(e) }(e) || function (e) { if (\"undefined\" != typeof Symbol && Symbol.iterator in Object(e)) return Array.from(e) }(e) || function (e, t) { if (e) { if (\"string\" == typeof e) return d(e, t); var n = Object.prototype.toString.call(e).slice(8, -1); return \"Object\" === n && e.constructor && (n = e.constructor.name), \"Map\" === n || \"Set\" === n ? Array.from(e) : \"Arguments\" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n) ? d(e, t) : void 0 } }(e) || function () { throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\") }() } function d(e, t) { (null == t || t > e.length) && (t = e.length); for (var n = 0, r = new Array(t); n < t; n++)r[n] = e[n]; return r } function v(e) { return Array.isArray ? Array.isArray(e) : \"[object Array]\" === b(e) } function g(e) { return \"string\" == typeof e } function y(e) { return \"number\" == typeof e } function p(e) { return !0 === e || !1 === e || function (e) { return m(e) && null !== e }(e) && \"[object Boolean]\" == b(e) } function m(t) { return \"object\" === e(t) } function k(e) { return null != e } function M(e) { return !e.trim().length } function b(e) { return null == e ? void 0 === e ? \"[object Undefined]\" : \"[object Null]\" : Object.prototype.toString.call(e) } var x = function (e) { return \"Invalid value for key \".concat(e) }, L = function (e) { return \"Pattern length exceeds max of \".concat(e, \".\") }, S = Object.prototype.hasOwnProperty, w = function () { function e(n) { var r = this; t(this, e), this._keys = [], this._keyMap = {}; var i = 0; n.forEach((function (e) { var t = _(e); i += t.weight, r._keys.push(t), r._keyMap[t.id] = t, i += t.weight })), this._keys.forEach((function (e) { e.weight /= i })) } return r(e, [{ key: \"get\", value: function (e) { return this._keyMap[e] } }, { key: \"keys\", value: function () { return this._keys } }, { key: \"toJSON\", value: function () { return JSON.stringify(this._keys) } }]), e }(); function _(e) { var t = null, n = null, r = null, i = 1; if (g(e) || v(e)) r = e, t = O(e), n = j(e); else { if (!S.call(e, \"name\")) throw new Error(function (e) { return \"Missing \".concat(e, \" property in key\") }(\"name\")); var o = e.name; if (r = o, S.call(e, \"weight\") && (i = e.weight) <= 0) throw new Error(function (e) { return \"Property 'weight' in key '\".concat(e, \"' must be a positive integer\") }(o)); t = O(o), n = j(o) } return { path: t, id: n, weight: i, src: r } } function O(e) { return v(e) ? e : e.split(\".\") } function j(e) { return v(e) ? e.join(\".\") : e } var A = c({}, { isCaseSensitive: !1, includeScore: !1, keys: [], shouldSort: !0, sortFn: function (e, t) { return e.score === t.score ? e.idx < t.idx ? -1 : 1 : e.score < t.score ? -1 : 1 } }, {}, { includeMatches: !1, findAllMatches: !1, minMatchCharLength: 1 }, {}, { location: 0, threshold: .6, distance: 100 }, {}, { useExtendedSearch: !1, getFn: function (e, t) { var n = [], r = !1; return function e(t, i, o) { if (k(t)) if (i[o]) { var c = t[i[o]]; if (!k(c)) return; if (o === i.length - 1 && (g(c) || y(c) || p(c))) n.push(function (e) { return null == e ? \"\" : function (e) { if (\"string\" == typeof e) return e; var t = e + \"\"; return \"0\" == t && 1 / e == -1 / 0 ? \"-0\" : t }(e) }(c)); else if (v(c)) { r = !0; for (var a = 0, s = c.length; a < s; a += 1)e(c[a], i, o + 1) } else i.length && e(c, i, o + 1) } else n.push(t) }(e, g(t) ? t.split(\".\") : t, 0), r ? n : n[0] }, ignoreLocation: !1, ignoreFieldNorm: !1 }), I = /[^ ]+/g; function C() { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : 3, t = new Map, n = Math.pow(10, e); return { get: function (e) { var r = e.match(I).length; if (t.has(r)) return t.get(r); var i = 1 / Math.sqrt(r), o = parseFloat(Math.round(i * n) / n); return t.set(r, o), o }, clear: function () { t.clear() } } } var E = function () { function e() { var n = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}, r = n.getFn, i = void 0 === r ? A.getFn : r; t(this, e), this.norm = C(3), this.getFn = i, this.isCreated = !1, this.setIndexRecords() } return r(e, [{ key: \"setSources\", value: function () { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : []; this.docs = e } }, { key: \"setIndexRecords\", value: function () { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : []; this.records = e } }, { key: \"setKeys\", value: function () { var e = this, t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : []; this.keys = t, this._keysMap = {}, t.forEach((function (t, n) { e._keysMap[t.id] = n })) } }, { key: \"create\", value: function () { var e = this; !this.isCreated && this.docs.length && (this.isCreated = !0, g(this.docs[0]) ? this.docs.forEach((function (t, n) { e._addString(t, n) })) : this.docs.forEach((function (t, n) { e._addObject(t, n) })), this.norm.clear()) } }, { key: \"add\", value: function (e) { var t = this.size(); g(e) ? this._addString(e, t) : this._addObject(e, t) } }, { key: \"removeAt\", value: function (e) { this.records.splice(e, 1); for (var t = e, n = this.size(); t < n; t += 1)this.records[t].i -= 1 } }, { key: \"getValueForItemAtKeyId\", value: function (e, t) { return e[this._keysMap[t]] } }, { key: \"size\", value: function () { return this.records.length } }, { key: \"_addString\", value: function (e, t) { if (k(e) && !M(e)) { var n = { v: e, i: t, n: this.norm.get(e) }; this.records.push(n) } } }, { key: \"_addObject\", value: function (e, t) { var n = this, r = { i: t, $: {} }; this.keys.forEach((function (t, i) { var o = n.getFn(e, t.path); if (k(o)) if (v(o)) !function () { for (var e = [], t = [{ nestedArrIndex: -1, value: o }]; t.length;) { var c = t.pop(), a = c.nestedArrIndex, s = c.value; if (k(s)) if (g(s) && !M(s)) { var u = { v: s, i: a, n: n.norm.get(s) }; e.push(u) } else v(s) && s.forEach((function (e, n) { t.push({ nestedArrIndex: n, value: e }) })) } r.$[i] = e }(); else if (!M(o)) { var c = { v: o, n: n.norm.get(o) }; r.$[i] = c } })), this.records.push(r) } }, { key: \"toJSON\", value: function () { return { keys: this.keys, records: this.records } } }]), e }(); function $(e, t) { var n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, r = n.getFn, i = void 0 === r ? A.getFn : r, o = new E({ getFn: i }); return o.setKeys(e.map(_)), o.setSources(t), o.create(), o } function R(e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.errors, r = void 0 === n ? 0 : n, i = t.currentLocation, o = void 0 === i ? 0 : i, c = t.expectedLocation, a = void 0 === c ? 0 : c, s = t.distance, u = void 0 === s ? A.distance : s, h = t.ignoreLocation, f = void 0 === h ? A.ignoreLocation : h, l = r / e.length; if (f) return l; var d = Math.abs(a - o); return u ? l + d / u : d ? 1 : l } function F() { for (var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : [], t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : A.minMatchCharLength, n = [], r = -1, i = -1, o = 0, c = e.length; o < c; o += 1) { var a = e[o]; a && -1 === r ? r = o : a || -1 === r || ((i = o - 1) - r + 1 >= t && n.push([r, i]), r = -1) } return e[o - 1] && o - r >= t && n.push([r, o - 1]), n } function P(e) { for (var t = {}, n = 0, r = e.length; n < r; n += 1) { var i = e.charAt(n); t[i] = (t[i] || 0) | 1 << r - n - 1 } return t } var N = function () { function e(n) { var r = this, i = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, o = i.location, c = void 0 === o ? A.location : o, a = i.threshold, s = void 0 === a ? A.threshold : a, u = i.distance, h = void 0 === u ? A.distance : u, f = i.includeMatches, l = void 0 === f ? A.includeMatches : f, d = i.findAllMatches, v = void 0 === d ? A.findAllMatches : d, g = i.minMatchCharLength, y = void 0 === g ? A.minMatchCharLength : g, p = i.isCaseSensitive, m = void 0 === p ? A.isCaseSensitive : p, k = i.ignoreLocation, M = void 0 === k ? A.ignoreLocation : k; if (t(this, e), this.options = { location: c, threshold: s, distance: h, includeMatches: l, findAllMatches: v, minMatchCharLength: y, isCaseSensitive: m, ignoreLocation: M }, this.pattern = m ? n : n.toLowerCase(), this.chunks = [], this.pattern.length) { var b = function (e, t) { r.chunks.push({ pattern: e, alphabet: P(e), startIndex: t }) }, x = this.pattern.length; if (x > 32) { for (var L = 0, S = x % 32, w = x - S; L < w;)b(this.pattern.substr(L, 32), L), L += 32; if (S) { var _ = x - 32; b(this.pattern.substr(_), _) } } else b(this.pattern, 0) } } return r(e, [{ key: \"searchIn\", value: function (e) { var t = this.options, n = t.isCaseSensitive, r = t.includeMatches; if (n || (e = e.toLowerCase()), this.pattern === e) { var i = { isMatch: !0, score: 0 }; return r && (i.indices = [[0, e.length - 1]]), i } var o = this.options, c = o.location, a = o.distance, s = o.threshold, u = o.findAllMatches, h = o.minMatchCharLength, f = o.ignoreLocation, d = [], v = 0, g = !1; this.chunks.forEach((function (t) { var n = t.pattern, i = t.alphabet, o = t.startIndex, y = function (e, t, n) { var r = arguments.length > 3 && void 0 !== arguments[3] ? arguments[3] : {}, i = r.location, o = void 0 === i ? A.location : i, c = r.distance, a = void 0 === c ? A.distance : c, s = r.threshold, u = void 0 === s ? A.threshold : s, h = r.findAllMatches, f = void 0 === h ? A.findAllMatches : h, l = r.minMatchCharLength, d = void 0 === l ? A.minMatchCharLength : l, v = r.includeMatches, g = void 0 === v ? A.includeMatches : v, y = r.ignoreLocation, p = void 0 === y ? A.ignoreLocation : y; if (t.length > 32) throw new Error(L(32)); for (var m, k = t.length, M = e.length, b = Math.max(0, Math.min(o, M)), x = u, S = b, w = d > 1 || g, _ = w ? Array(M) : []; (m = e.indexOf(t, S)) > -1;) { var O = R(t, { currentLocation: m, expectedLocation: b, distance: a, ignoreLocation: p }); if (x = Math.min(O, x), S = m + k, w) for (var j = 0; j < k;)_[m + j] = 1, j += 1 } S = -1; for (var I = [], C = 1, E = k + M, $ = 1 << k - 1, P = 0; P < k; P += 1) { for (var N = 0, D = E; N < D;) { var z = R(t, { errors: P, currentLocation: b + D, expectedLocation: b, distance: a, ignoreLocation: p }); z <= x ? N = D : E = D, D = Math.floor((E - N) / 2 + N) } E = D; var K = Math.max(1, b - D + 1), q = f ? M : Math.min(b + D, M) + k, W = Array(q + 2); W[q + 1] = (1 << P) - 1; for (var J = q; J >= K; J -= 1) { var T = J - 1, U = n[e.charAt(T)]; if (w && (_[T] = +!!U), W[J] = (W[J + 1] << 1 | 1) & U, P && (W[J] |= (I[J + 1] | I[J]) << 1 | 1 | I[J + 1]), W[J] & $ && (C = R(t, { errors: P, currentLocation: T, expectedLocation: b, distance: a, ignoreLocation: p })) <= x) { if (x = C, (S = T) <= b) break; K = Math.max(1, 2 * b - S) } } var V = R(t, { errors: P + 1, currentLocation: b, expectedLocation: b, distance: a, ignoreLocation: p }); if (V > x) break; I = W } var B = { isMatch: S >= 0, score: Math.max(.001, C) }; if (w) { var G = F(_, d); G.length ? g && (B.indices = G) : B.isMatch = !1 } return B }(e, n, i, { location: c + o, distance: a, threshold: s, findAllMatches: u, minMatchCharLength: h, includeMatches: r, ignoreLocation: f }), p = y.isMatch, m = y.score, k = y.indices; p && (g = !0), v += m, p && k && (d = [].concat(l(d), l(k))) })); var y = { isMatch: g, score: g ? v / this.chunks.length : 1 }; return g && r && (y.indices = d), y } }]), e }(), D = function () { function e(n) { t(this, e), this.pattern = n } return r(e, [{ key: \"search\", value: function () { } }], [{ key: \"isMultiMatch\", value: function (e) { return z(e, this.multiRegex) } }, { key: \"isSingleMatch\", value: function (e) { return z(e, this.singleRegex) } }]), e }(); function z(e, t) { var n = e.match(t); return n ? n[1] : null } var K = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = e === this.pattern; return { isMatch: t, score: t ? 0 : 1, indices: [0, this.pattern.length - 1] } } }], [{ key: \"type\", get: function () { return \"exact\" } }, { key: \"multiRegex\", get: function () { return /^=\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^=(.*)$/ } }]), i }(D), q = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = -1 === e.indexOf(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"inverse-exact\" } }, { key: \"multiRegex\", get: function () { return /^!\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^!(.*)$/ } }]), i }(D), W = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = e.startsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, this.pattern.length - 1] } } }], [{ key: \"type\", get: function () { return \"prefix-exact\" } }, { key: \"multiRegex\", get: function () { return /^\\^\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^\\^(.*)$/ } }]), i }(D), J = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = !e.startsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"inverse-prefix-exact\" } }, { key: \"multiRegex\", get: function () { return /^!\\^\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^!\\^(.*)$/ } }]), i }(D), T = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = e.endsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [e.length - this.pattern.length, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"suffix-exact\" } }, { key: \"multiRegex\", get: function () { return /^\"(.*)\"\\$$/ } }, { key: \"singleRegex\", get: function () { return /^(.*)\\$$/ } }]), i }(D), U = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = !e.endsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"inverse-suffix-exact\" } }, { key: \"multiRegex\", get: function () { return /^!\"(.*)\"\\$$/ } }, { key: \"singleRegex\", get: function () { return /^!(.*)\\$$/ } }]), i }(D), V = function (e) { a(i, e); var n = f(i); function i(e) { var r, o = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, c = o.location, a = void 0 === c ? A.location : c, s = o.threshold, u = void 0 === s ? A.threshold : s, h = o.distance, f = void 0 === h ? A.distance : h, l = o.includeMatches, d = void 0 === l ? A.includeMatches : l, v = o.findAllMatches, g = void 0 === v ? A.findAllMatches : v, y = o.minMatchCharLength, p = void 0 === y ? A.minMatchCharLength : y, m = o.isCaseSensitive, k = void 0 === m ? A.isCaseSensitive : m, M = o.ignoreLocation, b = void 0 === M ? A.ignoreLocation : M; return t(this, i), (r = n.call(this, e))._bitapSearch = new N(e, { location: a, threshold: u, distance: f, includeMatches: d, findAllMatches: g, minMatchCharLength: p, isCaseSensitive: k, ignoreLocation: b }), r } return r(i, [{ key: \"search\", value: function (e) { return this._bitapSearch.searchIn(e) } }], [{ key: \"type\", get: function () { return \"fuzzy\" } }, { key: \"multiRegex\", get: function () { return /^\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^(.*)$/ } }]), i }(D), B = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { for (var t, n = 0, r = [], i = this.pattern.length; (t = e.indexOf(this.pattern, n)) > -1;)n = t + i, r.push([t, n - 1]); var o = !!r.length; return { isMatch: o, score: o ? 0 : 1, indices: r } } }], [{ key: \"type\", get: function () { return \"include\" } }, { key: \"multiRegex\", get: function () { return /^'\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^'(.*)$/ } }]), i }(D), G = [K, B, W, J, U, T, q, V], H = G.length, Q = / +(?=([^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)/; function X(e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}; return e.split(\"|\").map((function (e) { for (var n = e.trim().split(Q).filter((function (e) { return e && !!e.trim() })), r = [], i = 0, o = n.length; i < o; i += 1) { for (var c = n[i], a = !1, s = -1; !a && ++s < H;) { var u = G[s], h = u.isMultiMatch(c); h && (r.push(new u(h, t)), a = !0) } if (!a) for (s = -1; ++s < H;) { var f = G[s], l = f.isSingleMatch(c); if (l) { r.push(new f(l, t)); break } } } return r })) } var Y = new Set([V.type, B.type]), Z = function () { function e(n) { var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, i = r.isCaseSensitive, o = void 0 === i ? A.isCaseSensitive : i, c = r.includeMatches, a = void 0 === c ? A.includeMatches : c, s = r.minMatchCharLength, u = void 0 === s ? A.minMatchCharLength : s, h = r.ignoreLocation, f = void 0 === h ? A.ignoreLocation : h, l = r.findAllMatches, d = void 0 === l ? A.findAllMatches : l, v = r.location, g = void 0 === v ? A.location : v, y = r.threshold, p = void 0 === y ? A.threshold : y, m = r.distance, k = void 0 === m ? A.distance : m; t(this, e), this.query = null, this.options = { isCaseSensitive: o, includeMatches: a, minMatchCharLength: u, findAllMatches: d, ignoreLocation: f, location: g, threshold: p, distance: k }, this.pattern = o ? n : n.toLowerCase(), this.query = X(this.pattern, this.options) } return r(e, [{ key: \"searchIn\", value: function (e) { var t = this.query; if (!t) return { isMatch: !1, score: 1 }; var n = this.options, r = n.includeMatches; e = n.isCaseSensitive ? e : e.toLowerCase(); for (var i = 0, o = [], c = 0, a = 0, s = t.length; a < s; a += 1) { var u = t[a]; o.length = 0, i = 0; for (var h = 0, f = u.length; h < f; h += 1) { var d = u[h], v = d.search(e), g = v.isMatch, y = v.indices, p = v.score; if (!g) { c = 0, i = 0, o.length = 0; break } if (i += 1, c += p, r) { var m = d.constructor.type; Y.has(m) ? o = [].concat(l(o), l(y)) : o.push(y) } } if (i) { var k = { isMatch: !0, score: c / i }; return r && (k.indices = o), k } } return { isMatch: !1, score: 1 } } }], [{ key: \"condition\", value: function (e, t) { return t.useExtendedSearch } }]), e }(), ee = []; function te(e, t) { for (var n = 0, r = ee.length; n < r; n += 1) { var i = ee[n]; if (i.condition(e, t)) return new i(e, t) } return new N(e, t) } var ne = \"$and\", re = \"$or\", ie = \"$path\", oe = \"$val\", ce = function (e) { return !(!e[ne] && !e[re]) }, ae = function (e) { return !!e[ie] }, se = function (e) { return !v(e) && m(e) && !ce(e) }, ue = function (e) { return i({}, ne, Object.keys(e).map((function (t) { return i({}, t, e[t]) }))) }; function he(e, t) { var n = t.ignoreFieldNorm, r = void 0 === n ? A.ignoreFieldNorm : n; e.forEach((function (e) { var t = 1; e.matches.forEach((function (e) { var n = e.key, i = e.norm, o = e.score, c = n ? n.weight : null; t *= Math.pow(0 === o && c ? Number.EPSILON : o, (c || 1) * (r ? 1 : i)) })), e.score = t })) } function fe(e, t) { var n = e.matches; t.matches = [], k(n) && n.forEach((function (e) { if (k(e.indices) && e.indices.length) { var n = { indices: e.indices, value: e.value }; e.key && (n.key = e.key.src), e.idx > -1 && (n.refIndex = e.idx), t.matches.push(n) } })) } function le(e, t) { t.score = e.score } function de(e, t) { var n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, r = n.includeMatches, i = void 0 === r ? A.includeMatches : r, o = n.includeScore, c = void 0 === o ? A.includeScore : o, a = []; return i && a.push(fe), c && a.push(le), e.map((function (e) { var n = e.idx, r = { item: t[n], refIndex: n }; return a.length && a.forEach((function (t) { t(e, r) })), r })) } var ve = function () { function e(n) { var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, i = arguments.length > 2 ? arguments[2] : void 0; t(this, e), this.options = c({}, A, {}, r), this.options.useExtendedSearch, this._keyStore = new w(this.options.keys), this.setCollection(n, i) } return r(e, [{ key: \"setCollection\", value: function (e, t) { if (this._docs = e, t && !(t instanceof E)) throw new Error(\"Incorrect 'index' type\"); this._myIndex = t || $(this.options.keys, this._docs, { getFn: this.options.getFn }) } }, { key: \"add\", value: function (e) { k(e) && (this._docs.push(e), this._myIndex.add(e)) } }, { key: \"remove\", value: function () { for (var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : function () { return !1 }, t = [], n = 0, r = this._docs.length; n < r; n += 1) { var i = this._docs[n]; e(i, n) && (this.removeAt(n), n -= 1, r -= 1, t.push(i)) } return t } }, { key: \"removeAt\", value: function (e) { this._docs.splice(e, 1), this._myIndex.removeAt(e) } }, { key: \"getIndex\", value: function () { return this._myIndex } }, { key: \"search\", value: function (e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.limit, r = void 0 === n ? -1 : n, i = this.options, o = i.includeMatches, c = i.includeScore, a = i.shouldSort, s = i.sortFn, u = i.ignoreFieldNorm, h = g(e) ? g(this._docs[0]) ? this._searchStringList(e) : this._searchObjectList(e) : this._searchLogical(e); return he(h, { ignoreFieldNorm: u }), a && h.sort(s), y(r) && r > -1 && (h = h.slice(0, r)), de(h, this._docs, { includeMatches: o, includeScore: c }) } }, { key: \"_searchStringList\", value: function (e) { var t = te(e, this.options), n = this._myIndex.records, r = []; return n.forEach((function (e) { var n = e.v, i = e.i, o = e.n; if (k(n)) { var c = t.searchIn(n), a = c.isMatch, s = c.score, u = c.indices; a && r.push({ item: n, idx: i, matches: [{ score: s, value: n, norm: o, indices: u }] }) } })), r } }, { key: \"_searchLogical\", value: function (e) { var t = this, n = function (e, t) { var n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, r = n.auto, i = void 0 === r || r, o = function e(n) { var r = Object.keys(n), o = ae(n); if (!o && r.length > 1 && !ce(n)) return e(ue(n)); if (se(n)) { var c = o ? n[ie] : r[0], a = o ? n[oe] : n[c]; if (!g(a)) throw new Error(x(c)); var s = { keyId: j(c), pattern: a }; return i && (s.searcher = te(a, t)), s } var u = { children: [], operator: r[0] }; return r.forEach((function (t) { var r = n[t]; v(r) && r.forEach((function (t) { u.children.push(e(t)) })) })), u }; return ce(e) || (e = ue(e)), o(e) }(e, this.options), r = this._myIndex.records, i = {}, o = []; return r.forEach((function (e) { var r = e.$, c = e.i; if (k(r)) { var a = function e(n, r, i) { if (!n.children) { var o = n.keyId, c = n.searcher, a = t._findMatches({ key: t._keyStore.get(o), value: t._myIndex.getValueForItemAtKeyId(r, o), searcher: c }); return a && a.length ? [{ idx: i, item: r, matches: a }] : [] } switch (n.operator) { case ne: for (var s = [], u = 0, h = n.children.length; u < h; u += 1) { var f = e(n.children[u], r, i); if (!f.length) return []; s.push.apply(s, l(f)) } return s; case re: for (var d = [], v = 0, g = n.children.length; v < g; v += 1) { var y = e(n.children[v], r, i); if (y.length) { d.push.apply(d, l(y)); break } } return d } }(n, r, c); a.length && (i[c] || (i[c] = { idx: c, item: r, matches: [] }, o.push(i[c])), a.forEach((function (e) { var t, n = e.matches; (t = i[c].matches).push.apply(t, l(n)) }))) } })), o } }, { key: \"_searchObjectList\", value: function (e) { var t = this, n = te(e, this.options), r = this._myIndex, i = r.keys, o = r.records, c = []; return o.forEach((function (e) { var r = e.$, o = e.i; if (k(r)) { var a = []; i.forEach((function (e, i) { a.push.apply(a, l(t._findMatches({ key: e, value: r[i], searcher: n }))) })), a.length && c.push({ idx: o, item: r, matches: a }) } })), c } }, { key: \"_findMatches\", value: function (e) { var t = e.key, n = e.value, r = e.searcher; if (!k(n)) return []; var i = []; if (v(n)) n.forEach((function (e) { var n = e.v, o = e.i, c = e.n; if (k(n)) { var a = r.searchIn(n), s = a.isMatch, u = a.score, h = a.indices; s && i.push({ score: u, key: t, value: n, idx: o, norm: c, indices: h }) } })); else { var o = n.v, c = n.n, a = r.searchIn(o), s = a.isMatch, u = a.score, h = a.indices; s && i.push({ score: u, key: t, value: o, norm: c, indices: h }) } return i } }]), e }(); return ve.version = \"6.4.6\", ve.createIndex = $, ve.parseIndex = function (e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.getFn, r = void 0 === n ? A.getFn : n, i = e.keys, o = e.records, c = new E({ getFn: r }); return c.setKeys(i), c.setIndexRecords(o), c }, ve.config = A, function () { ee.push.apply(ee, arguments) }(Z), ve }, \"object\" == typeof exports && \"undefined\" != typeof module ? module.exports = t() : \"function\" == typeof define && define.amd ? define(t) : (e = e || self).Fuse = t();\n", "/*\n * Some notes on how this works...\n *\n * paletteData is passed into the constructor and is the initial list of items\n * these are TurboAdminMenuItem objects\n *\n * At any point, buildPaletteItems() can be called to turn the paletteData\n * into an array of \"li\" nodes.\n *\n * updatePaletteItems inserts the paletteItems into the \"ul\" list and sets the\n * selectedElement\n *\n * The selectedItem is always one of the paletteItems\n *\n * paletteSearch rebuilds the paletteItems from the paletteData using\n * buildPaletteItems, and then filters the list with FuseJS\n */\n\nimport Fuse from './fuse-6.4.6.js';\nimport TurboAdminMenuItem from './types/class-turbo-admin-menu-item';\nimport ContentApi from './apis/class-content-api.js';\nimport SearchMode from './types/class-search-mode.js';\nimport ContentItem from './types/class-content-item.js';\n\nexport default class TurboAdminPalette {\n\n\tconstructor(paletteData, options) {\n\n\t\tconsole.log('Initialising TurboAdmin');\n\n        this.options = options;\n\n        /** @type {HTMLDivElement} */\n        this.paletteElement      = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-container'));\n        /** @type {HTMLDivElement} */\n        this.paletteInnerElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette'));\n\t\t/** @type {HTMLInputElement} */\n        this.paletteInputElement = /** @type {HTMLInputElement} */ (document.getElementById('ta-command-palette-input'));\n\t\t/** @type {HTMLDivElement} */\n        this.paletteItemsContainerElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-items-container'));\n\t\t/** @type {HTMLUListElement} */\n        this.paletteItemsElement = /** @type {HTMLUListElement} */ (document.getElementById('ta-command-palette-items'));\n\t\t/** @type {HTMLDivElement} */\n        this.paletteSubmenuContainerElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-submenu-container'));\n        /** @type {HTMLDivElement} */\n        this.paletteSearchModeTag = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-search-mode-tag'));\n        /** @type {HTMLDivElement} */\n        this.paletteSearchModeTabNotice = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-tab-notice'));\n        /** @type {HTMLSpanElement} */\n        this.paletteSearchModeTabNoticeText = /** @type {HTMLSpanElement} */ (document.getElementById('ta-command-palette-tab-notice-text'));\n        /** @type {HTMLDivElement} */\n        this.paletteNoticeElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-notice'));\n\n\n        // Add a class if the menu needs refreshing with a visit to the Dashboard\n        if (globalThis.turboAdmin.menuNeedsRefresh) {\n            this.showPaletteNotice('Menu needs refreshing. Visit the Dashboard to refresh.');\n        }\n\n        // We need this when injecting items. We use it to help generate edit URLs. Not the best way but\n        // works for now.\n        /** @type {HTMLUListElement} */\n        this.profileLinkElem = document.getElementById('wp-admin-bar-edit-profile');\n        /** @type {null|String} */\n        this.profileLink = null;\n        if (this.profileLinkElem) {\n            this.profileLink = this.profileLinkElem.querySelector('a').href;\n        }\n\n\t\t// Get palette data\n\t\tthis.paletteData = paletteData;\n\n        // Backup of the palette data for use when we enter a different search mode\n\t\tthis.paletteDataBackup = null;\n\t\tthis.paletteItemsBackup = null;\n        this.paletteItemIndexBackup = null;\n\n        // Current search modes/keyword\n        this.searchMode = null;\n\n        // paletteItems is the list of 'li' elements used to build the palette\n        this.paletteItems = [];\n\n        // itemIndex is a \"cache\" of URLs used to check if we already\n        // have an item in the palette\n        this.itemIndex = {};\n\n        // Convert into LI elements\n        this.buildPaletteItems();\n\n\n\t\tthis.selectedItem = this.paletteItems[0];\n        this.openedSubMenu = null;\n        this.selectedSubItem = null;\n\n\t\t// Add them to the DOM\n\t\tthis.updatePaletteItems();\n\n        // Set state\n        this.navigating = false;\n        this.debounceTimeout;\n\n\t\tthis.paletteFuseOptions = [];\n\t\tthis.paletteFuse = null;\n\n\t\tif (typeof (Fuse) !== 'function') {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.paletteFuseOptions = {\n\t\t\tkeys: ['innerText'],\n\t\t}\n\n\t\tthis.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);\n\n\t\tdocument.addEventListener('keydown', e => this.handleGlobalKey(e));\n\n\t\tthis.paletteElement.addEventListener('click', e => {\n\t\t\tthis.checkForPaletteItemClick(e);\n            this.checkForClickToClose(e);\n\t\t});\n\n        this.paletteItemsElement.addEventListener('mouseover', e => {\n            this.setHoveredItem(e.target);\n        });\n\t}\n\n    htmlDecode(input) {\n        var doc = new DOMParser().parseFromString(input, \"text/html\");\n        return doc.documentElement.textContent;\n    }\n\n    isMac() {\n        return navigator.platform.startsWith('Mac');\n    }\n\n    metaPressed(e) {\n        return this.isMac() ? e.metaKey : e.ctrlKey;\n    }\n\n    inSearchMode() {\n        return this.searchMode !== null;\n    }\n\n\t/**\n     * This converts this.paletteData into a list of paletteListItems in this.paletteItems\n     *\n     * It also builds the itemIndex\n     */\n    buildPaletteItems() {\n        this.paletteItems = [];\n        this.itemIndex = {};\n\n\t\tthis.paletteData.forEach(item => {\n\t\t\tconst li = document.createElement('li');\n\t\t\tconst a = document.createElement('a');\n\t\t\tli.appendChild(a);\n\t\t\ta.href = item.action;\n\t\t\tlet title = item.title;\n\t\t\tif (item.parentTitle) {\n\t\t\t\ttitle = item.parentTitle + \": \" + title;\n\t\t\t}\n\t\t\ta.innerHTML = title;\n            this.addPaletteListItem(li);\n\t\t});\n\t}\n\n    // This takes a 'li' element and adds it to the paletteItems.\n    // It also updates any caches and stuff.\n    addPaletteListItem(listItem) {\n        this.paletteItems.push(listItem);\n\n        const link = listItem.querySelector('a');\n        if (link) {\n            this.itemIndex[link.href] = 1;\n        }\n    }\n\n    contentItemExists(url) {\n        return Boolean(this.itemIndex[url]);\n    }\n\n    /**\n     * Clears and sets the content items\n     *\n     * @param {ContentItem[]} contentItems\n     */\n    setContentItems(contentItems) {\n        this.paletteItems = [];\n        this.itemIndex = [];\n        this.injectContentItems(contentItems, false);\n    }\n\n    /**\n     * Content items have:\n     *  title\n     *  subtype\n     *  url\n     *  (we should also make the sub-menu definable, but that's not done yet)\n     *\n     * @param {ContentItem[]} contentItems\n     */\n    injectContentItems(contentItems, andRunSearch = true) {\n        console.log('Injecting items');\n\n        if (contentItems.length > 0) {\n            contentItems.forEach(this.injectItem.bind(this));\n        }\n\n        if (andRunSearch) {\n            // Reset the search to work on the new items\n            this.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);\n            this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map(i => i.item);\n        }\n\n        this.updatePaletteItems();\n    }\n\n    /**\n     * Injects a single content item into the palette\n     *\n     * @param {ContentItem} item\n     */\n    injectItem(item) {\n        const itemTitle = item.title;\n        // const itemTitle = item.title.rendered;\n        const itemType = item.subtype;\n        const itemUrl = item.url;\n\n        // console.log('Adding item: ' + itemTitle);\n\n        // // Check if item already exists\n        if (this.contentItemExists(itemUrl)) {\n            console.log('Not adding duplicate');\n            return;\n        }\n\n        let title = itemTitle;\n\n        if (itemType) {\n            const itemTypeName = globalThis.contentApi.postTypes[itemType] ? globalThis.contentApi.postTypes[itemType].name : itemType;\n            title += ` (${itemTypeName})`;\n        }\n\n        const li = document.createElement('li');\n        const a = document.createElement('a');\n        let subMenu = null;\n\n        // Loop over submenu items OR add link.\n        if (item.submenuItems.length > 0) {\n\n            // Prepare the outer sub-menu elements\n            subMenu = document.createElement('div');\n            const subMenuTitle = document.createElement('div');\n            const subMenuItems = document.createElement('ul');\n            subMenu.classList.add('ta-submenu');\n            subMenuTitle.classList.add('ta-submenu-title');\n\n            subMenuTitle.textContent = this.htmlDecode(itemTitle);\n            subMenuItems.classList.add('ta-submenu-items');\n            subMenu.appendChild(subMenuTitle);\n\n            for (let i = 0; i < item.submenuItems.length; i++) {\n                const subMenuItem = item.submenuItems[i]\n                // TODO: Abstract this so sub-menus can be defined by plugins?\n                const subMenuListItem = document.createElement('li');\n                const subMenuLink = document.createElement('a');\n                subMenuLink.innerText = subMenuItem.title;\n                subMenuLink.href = subMenuItem.url;\n                for (let a = 0; a < subMenuItem.attributes.length; a++) {\n                    subMenuLink.setAttribute(\n                        subMenuItem.attributes[a].name,\n                        subMenuItem.attributes[a].value\n                    )\n                }\n                subMenuListItem.appendChild(subMenuLink);\n                subMenuItems.appendChild(subMenuListItem);\n            }\n\n            // Add the sub-menu items UL to the sub-menu element.\n            subMenu.appendChild(subMenuItems);\n\n            li.classList.add('ta-has-child-menu');\n        }\n\n        a.href = itemUrl;\n        a.innerHTML = title;\n\n        li.appendChild(a);\n        if (subMenu !== null) {\n            li.appendChild(subMenu);\n        }\n\n        this.addPaletteListItem(li);\n    }\n\n\t/**\n     * Handle global keypresses (at document level). Note that other key presses\n     * are handled by paletteActions()\n     *\n     * @param {KeyboardEvent} e\n     */\n    async handleGlobalKey(e) {\n\t\tif (this.shortcutKeysPressed(e)) {\n            e.preventDefault();\n            e.stopPropagation();\n\t\t\tif (this.paletteShown()) {\n\t\t\t\tthis.hidePalette();\n\t\t\t} else {\n\t\t\t\tthis.showPalette();\n\t\t\t}\n            return;\n\t\t}\n\n\t\tif (e.code === 'Escape' && this.paletteShown()) {\n\t\t\tif (this.isSubMenuOpen()){\n                this.closeSubMenu();\n            } else if (this.inSearchMode()) {\n                this.leaveSearchMode();\n            } else {\n                this.hidePalette();\n            }\n            return;\n\t\t}\n\n        if (this.paletteShown()) {\n            await this.paletteActions(e);\n\t\t}\n\t}\n\n\tshortcutKeysPressed(keyEvent) {\n        // The reduce here works through all the different possible key combos\n        // (more than one can be specified in options)\n\t\tconst keysPressed = this.options.shortcutKeys.reduce(\n\t\t\t(keyPressed, combo) => {\n\t\t\t\tif (keyPressed) {\n\t\t\t\t\treturn keyPressed;\n\t\t\t\t}\n                return ((!navigator.platform.startsWith('Mac')) || (combo.meta === keyEvent.metaKey))\n                    && (combo.alt === keyEvent.altKey)\n                    && (combo.shift === keyEvent.shiftKey)\n                    && (combo.ctrl === keyEvent.ctrlKey)\n                    && (\n                        keyEvent.code === 'Key' + combo.key.toUpperCase()\n                        || ( combo.key === ' ' && keyEvent.code.toUpperCase() === 'SPACE' )\n                    );\n            }, false);\n\t\treturn keysPressed;\n\t}\n\n    /*\n     * Adds the tab hint for a keyword once it has been typed.\n     */\n    maybeHighlightInputKeyword(newKey) {\n        // Do nothing if we are in a search-mode\n        if (this.inSearchMode()) {\n            return;\n        }\n\n        // This is fired on \"keyDown\", so the value isn't update with the new key yet.\n        // But don't do this for special keys, and catch backspace too.\n        let newInputValue = this.paletteInputElement.value;\n        if (newKey.length === 1) {\n            newInputValue += newKey;\n        }\n        if (newKey === 'Backspace') {\n            newInputValue = newInputValue.slice(0, -1);\n        }\n        // console.log(`Checking palette input value ${newInputValue} for keyword`);\n        if (this.isKeyword(newInputValue)) {\n            this.paletteSearchModeTabNoticeText.innerText = `Search for ${newInputValue}`;\n            this.paletteSearchModeTabNotice.classList.add('active');\n        } else {\n            this.unhighlightInputKeyword();\n        }\n    }\n\n    unhighlightInputKeyword() {\n        this.paletteSearchModeTabNotice.classList.remove('active');\n    }\n\n    async debouncedPaletteSearchAndUpdate() {\n        // If we're not in a search mode then search immediately\n        if (! this.inSearchMode()) {\n            this.debounceTimeout = null;\n            await this.paletteSearchAndUpdate();\n            return;\n        }\n\n        // If timer is null, reset it to 500ms and run your functions.\n        // Otherwise, wait until timer is cleared\n\n        // Cancel the existing timeout\n        clearTimeout(this.debounceTimeout)\n\n        this.debounceTimeout = setTimeout(async function () {\n            // Reset timeout\n            this.debounceTimeout = null;\n\n            // Run the search function\n            await this.paletteSearchAndUpdate();\n        }.bind(this), 750);\n    }\n\n    /**\n     * Check if a string is a search mode keyword\n     *\n     * @param {string} inputString\n     * @returns {boolean}\n     */\n    isKeyword(inputString) {\n        return Object.keys(globalThis.turboAdmin.searchModes).includes(inputString);\n    }\n\n    /**\n     * Show the palette notice with the specified text\n     *\n     * @param {string} text\n     */\n    showPaletteNotice(text) {\n        this.paletteNoticeElement.classList.add('active');\n        this.paletteNoticeElement.innerText = text;\n    }\n\n    /**\n     * Hide the palette notice\n     */\n    hidePaletteNotice() {\n        this.paletteNoticeElement.classList.remove('active');\n    }\n\n\t/**\n     * Handle (non-global) keypresses on the palette\n     *\n     * @param {KeyboardEvent} e\n     * @returns {Promise}\n     */\n    async paletteActions(e) {\n\t\tif (e.code === 'ArrowDown' && this.paletteShown()) {\n\t\t\te.preventDefault();\n\t\t\tthis.moveDown();\n\t\t\treturn;\n\t\t}\n\t\tif (e.code === 'ArrowUp' && this.paletteShown()) {\n\t\t\te.preventDefault();\n\t\t\tthis.moveUp();\n\t\t\treturn;\n\t\t}\n\t\tif (e.code === 'Enter' && this.paletteShown()) {\n            e.preventDefault();\n            this.doAction(this.metaPressed(e));\n            return;\n\t\t}\n\n        /*\n         * Only the actions above can be done in sub-menus.\n         */\n        if (this.isSubMenuOpen()) {\n            return;\n        }\n\n        /*\n         * Check for a keyword being typed and add a UI hint.\n         */\n        this.maybeHighlightInputKeyword(e.key);\n\n        /*\n         * Tabbing looks for a search mode keyword.\n         */\n        if (! this.inSearchMode() && (e.code === 'Tab' || e.key === ':')) {\n            console.log('Checking for search mode');\n            let inputValue = this.paletteInputElement.value;\n            if (this.isKeyword(inputValue)) {\n                console.log('Found search mode ' + inputValue)\n                e.preventDefault();\n                // TODO: Work on this.\n                await this.enterSearchMode(\n                    globalThis.turboAdmin.searchModes[inputValue]);\n                return;\n            }\n        }\n\n        /*\n         * Backspace may exit us from a search mode\n         */\n        if (this.inSearchMode() && e.code === 'Backspace' && this.paletteInputElement.value === '') {\n            e.preventDefault();\n            this.leaveSearchMode();\n            return;\n        }\n\n\t\tawait this.debouncedPaletteSearchAndUpdate();\n\t}\n\n    /**\n     * Puts the palette into a specific search mode - used when a keyword is selected\n     *\n     * @param {SearchMode} searchMode\n     */\n    async enterSearchMode(searchMode) {\n        console.log('Entering search mode for keyword ' + searchMode.keyword);\n        this.backupPaletteData();\n\n        this.paletteData = [];\n        this.paletteItems = [];\n        this.itemIndex = [];\n\n        // Remove the notice if it's there\n        this.hidePaletteNotice();\n\n        this.searchMode = searchMode;\n        this.paletteInputElement.value = '';\n        this.addSearchModeTag(searchMode.displayName);\n        this.unhighlightInputKeyword();\n        this.updatePaletteItems();\n        // This is similar to code in paletteSearch - maybe we could extract/abstract it?\n        if (searchMode.defaultItemsCallback !== null) {\n            this.paletteInnerElement.classList.add('loading');\n            const results = await searchMode.defaultItemsCallback();\n            this.setContentItems(results);\n            // this.injectContentItems(results);\n            this.paletteInnerElement.classList.remove('loading');\n        }\n    }\n\n    /**\n     * Leaves the current search mode\n     */\n    leaveSearchMode() {\n        const searchMode = this.searchMode;\n        // It's important what we set this to - see inSearchMode()\n        this.searchMode = null;\n        this.removeSearchModeTag();\n        this.restorePaletteData();\n        this.paletteInputElement.value = searchMode.keyword;\n        this.maybeHighlightInputKeyword('');\n        this.paletteSearchAndUpdate();\n    }\n\n    /**\n     * Backups up the palette data to a local variable so that it can be\n     * restored later.\n     */\n    backupPaletteData() {\n        this.paletteDataBackup = this.paletteData;\n        this.paletteItemsBackup = this.paletteItems;\n        this.paletteItemIndexBackup = this.itemIndex;\n    }\n\n    /**\n     * Restores the save palette data - does not rebuild anything\n     */\n    restorePaletteData() {\n        this.paletteData = this.paletteDataBackup;\n        this.paletteItems = this.paletteItemsBackup;\n        this.itemIndex = this.paletteItemIndexBackup;\n    }\n\n    /**\n     * Adds the search mode tag with the specified title.\n     *\n     * @param {string} title\n     */\n    addSearchModeTag(title) {\n        this.paletteSearchModeTag.classList.add('active');\n        this.paletteSearchModeTag.innerText = title;\n    }\n\n    /**\n     * Removes the search mode tag\n     */\n    removeSearchModeTag() {\n        this.paletteSearchModeTag.classList.remove('active');\n    }\n\n    isPaletteOpen() {\n        return this.paletteElement?.classList.contains('active');\n    }\n\n\tshowPalette() {\n        // Bail if already shown (this can be triggered by a focus event)\n        if (this.isPaletteOpen()) {\n            return;\n        }\n\n        this.paletteInputElement.value = '';\n\t\tthis.paletteInputElement?.focus();\n\t\tthis.paletteElement?.classList.add('active');\n        // This is needed in admin-bar mode otherwise it gets a weird already-scrolled thing when\n        // the palette opens.\n        setTimeout(() => this.paletteItemsElement.scrollTop = 0, 100);\n\t}\n\n\thidePalette() {\n        this.navigating = false;\n\t\tthis.paletteElement?.classList.remove('active');\n        this.paletteInputElement.value = '';\n        this.paletteInputElement.blur();\n        if (this.isSubMenuOpen()) {\n            this.closeSubMenu();\n        }\n        if (this.searchMode !== null) {\n            this.leaveSearchMode();\n        }\n\t}\n\n\tpaletteShown() {\n\t\treturn this.paletteElement?.classList.contains('active');\n\t}\n\n    checkForPaletteItemClick(e) {\n        if (e.target.tagName === 'A') {\n            e.preventDefault();\n            if (this.isSubMenuOpen()) {\n                this.selectedSubItem = e.target.closest('li');\n            } else {\n                this.selectedItem = e.target.closest('li');\n            }\n            this.setSelectedElement();\n\n            this.doAction(this.metaPressed(e));\n        }\n    }\n\n\tcheckForClickToClose(e) {\n\t\tif (e.target.id === this.paletteElement.id) {\n\t\t\tthis.hidePalette();\n\t\t}\n\t}\n\n\tsetSelectedElement() {\n        if (this.isSubMenuOpen()) {\n            this.paletteSubmenuContainerElement?.querySelectorAll('.ta-submenu li.selected')?.forEach(e => e.classList.remove('selected'));\n            this.selectedSubItem.classList.add('selected');\n        } else {\n            this.paletteItemsElement?.querySelectorAll('li.selected')?.forEach(e => e.classList.remove('selected'));\n            if (this.selectedItem) {\n                this.selectedItem.classList.add('selected');\n                this.scrollList();\n            }\n        }\n\t}\n\n\tscrollList() {\n\t\t// Scrolling up\n\t\tif (this.selectedItem.offsetTop < this.paletteItemsElement.scrollTop) {\n\t\t\tthis.paletteItemsElement.scrollTop = this.selectedItem.offsetTop;\n\t\t}\n\t\t// Scrolling down\n\t\tif (this.selectedItem.offsetTop + this.selectedItem.offsetHeight > this.paletteItemsElement.offsetHeight + this.paletteItemsElement.scrollTop) {\n\t\t\tthis.paletteItemsElement.scrollTop = this.selectedItem.offsetTop + this.selectedItem.offsetHeight - this.paletteItemsElement.offsetHeight;\n\t\t}\n\t}\n\n    setHoveredItem(element) {\n        // Only do this for li's\n        if ('LI' === element.tagName) {\n            this.navigating = true;\n            if (this.isSubMenuOpen()) {\n                this.selectedSubItem = element;\n            } else {\n                this.selectedItem = element;\n            }\n            this.setSelectedElement();\n        }\n    }\n\n\tmoveDown() {\n        if (this.isSubMenuOpen()) {\n            const nextItem = this.selectedSubItem.nextElementSibling;\n            this.navigating = true;\n            if (nextItem) {\n                this.selectedSubItem = nextItem;\n                this.setSelectedElement();\n            }\n        } else {\n            const nextItem = this.selectedItem.nextElementSibling;\n            this.navigating = true;\n            if (nextItem) {\n                this.selectedItem = nextItem;\n                this.setSelectedElement();\n            }\n        }\n\t}\n\n\tmoveUp() {\n        if (this.isSubMenuOpen()) {\n            const prevItem = this.selectedSubItem.previousElementSibling;\n            this.navigating = true;\n            if (prevItem) {\n                this.selectedSubItem = prevItem;\n                this.setSelectedElement();\n            }\n        } else {\n            const prevItem = this.selectedItem.previousElementSibling;\n            this.navigating = true;\n            if (prevItem) {\n                this.selectedItem = prevItem;\n                this.setSelectedElement();\n            }\n        }\n    }\n\n    isSubMenuOpen() {\n        return null !== this.openedSubMenu;\n    }\n\n    openSubMenu(subMenuElement) {\n        this.paletteSubmenuContainerElement.replaceChildren(subMenuElement);\n        // Set height in case main menu is smaller than sub menu\n        const subMenuHeight = this.paletteSubmenuContainerElement.offsetHeight;\n        this.paletteItemsContainerElement.style.minHeight = subMenuHeight + \"px\";\n        this.paletteSubmenuContainerElement.classList.add('active');\n\n        this.selectedSubItem = subMenuElement.querySelector('li');\n        this.openedSubMenu = subMenuElement;\n        this.setSelectedElement();\n\n        this.paletteInputElement.disabled = true;\n        // Blur the input so that keys can continue to be captured\n        this.paletteInputElement.blur();\n    }\n\n    closeSubMenu(subMenuElement = null) {\n        if (null === subMenuElement) {\n            subMenuElement = document.querySelector('.ta-submenu.active');\n        }\n        this.paletteSubmenuContainerElement.classList.remove('active');\n        this.selectedSubItem.classList.remove('active');\n        this.paletteItemsContainerElement.style.minHeight = 'auto';\n        this.selectedSubItem = null;\n        this.openedSubMenu = null;\n        this.paletteInputElement.disabled = false;\n        this.paletteInputElement.focus();\n    }\n\n\tdoAction(metaPressed = false) {\n        if (this.isSubMenuOpen()) {\n            this.actOnItem(this.selectedSubItem, metaPressed);\n            return;\n        }\n        if (this.selectedItem.classList.contains('ta-has-child-menu')) {\n            const subMenu = this.selectedItem.querySelector('.ta-submenu');\n            this.openSubMenu(subMenu);\n            return;\n        }\n\n        this.actOnItem(this.selectedItem, metaPressed);\n    }\n\n    actOnItem(item, metaPressed) {\n        this.hidePalette();\n        const link = item.querySelector('a');\n        const url = link.href;\n\n        // link.href will be interpolated by the browser, so if it's empty it will be the current page\n        // use getAttribute instead to work out if its empty\n        if (link.getAttribute('href') === '') {\n            return;\n        }\n\n        if ('clipboard' === link.dataset.action) {\n            navigator.clipboard.writeText(url);\n            return;\n        }\n\n        if (metaPressed) {\n            window.open(url, '_blank');\n        } else {\n            window.location = url;\n        }\n    }\n\n\tselectedItemDisplayed() {\n\t\treturn Array.from(this.paletteItemsElement.childNodes).includes(this.selectedItem);\n\t}\n\n\tasync paletteSearchAndUpdate() {\n\t\tawait this.paletteSearch();\n\t\tthis.updatePaletteItems();\n\t}\n\n\tasync paletteSearch() {\n        // Get the value...\n        // const response = await globalThis.contentApi.get('posts', { search: this.paletteInputElement.value, per_page: 100, status: ['publish', 'future', 'draft', 'pending', 'private'] });\n\n        if (! this.searchMode) {\n            this.buildPaletteItems();\n\n            if (this.paletteInputElement.value !== '') {\n                // Reset the search to work on the new items\n                this.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);\n                this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map(i => i.item);\n            }\n            return;\n        }\n\n        if (this.paletteInputElement.value.length === 0) {\n            this.paletteInnerElement.classList.add('loading');\n            let results = [];\n            if (this.searchMode.defaultItemsCallback !== null) {\n                results = await this.searchMode.defaultItemsCallback();\n            }\n            this.setContentItems(results);\n            // this.injectContentItems(results);\n            this.paletteInnerElement.classList.remove('loading');\n        } else {\n            // This is copied to enterSearchMode. Should probably be extracted.\n            this.paletteInnerElement.classList.add('loading');\n            const results = await this.searchMode.searchCallback(this.paletteInputElement.value);\n            this.setContentItems(results);\n            // this.injectContentItems(results);\n            this.paletteInnerElement.classList.remove('loading');\n        }\n\n        /**\n         * OLD CODE BELOW\n         */\n        // Content search - don't search everything!\n        // if (globalThis.contentApi.active && this.postTypes !== [] && this.paletteInputElement.value.length > 2) {\n        //     this.paletteInnerElement.classList.add('loading');\n\n        //     globalThis.contentApi.getPosts(this.paletteInputElement.value)\n        //         .then(\n        //             results => {\n        //                     this.injectContentItems(results);\n        //                     this.paletteInnerElement.classList.remove('loading');\n        //             }\n        //         )\n        // }\n\t}\n\n\tupdatePaletteItems() {\n\t\tconst newItems = document.createElement('ul');\n\t\tnewItems.id = 'ta-command-palette-items';\n\n\t\tthis.paletteItems.forEach(i => {\n\t\t\tnewItems.appendChild(i);\n\t\t})\n\n\t\tthis.paletteItemsElement.replaceChildren(...newItems.children);\n\n\t\tif (!this.navigating || !this.selectedItemDisplayed()) {\n\t\t\tthis.selectedItem = this.paletteItems[0];\n\t\t}\n\n\t\tthis.setSelectedElement();\n\t}\n\n}\n", "/**\n * Menu items are the items ready to appear in the palette.\n *\n * These are standard items, not content items. Though this should probably be standardised.\n */\nexport default class TurboAdminMenuItem {\n\n    /**\n     * The title of the item\n     *\n     * @type {string}\n     */\n    title = '';\n\n    /**\n     * The action of the item is the URL to visit when the item is clicked\n     *\n     * @type {string}\n     */\n    action = '';\n\n    /**\n     * The parent title is the title of the parent item under which the current item\n     * was found in the WordPress menu.\n     *\n     * e.g. in Posts -> Add Post, \"Posts\" is the parent item.\n     *\n     * @type {string}\n     */\n    parentTitle = '';\n\n    /**\n     * True if the item is not to be cached. Used for things like post-specific links like \"Edit post\"\n     *\n     * @type {boolean}\n     */\n    noCache = false;\n\n\tconstructor(title, action, parentTitle, noCache = false) {\n\t\tthis.title = title;\n\t\tthis.action = action;\n\t\tthis.parentTitle = parentTitle;\n        this.noCache = noCache;\n\t}\n\n    sameAs(item) {\n        return item.title === this.title &&\n            item.action === this.action &&\n            item.parentTitle === this.parentTitle;\n    }\n}\n", "/**\n * This class is an abstraction of the browser extension storage API\n * (see https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage)\n * but that falls back to using regular localStorage if we're not in a\n * browser extension.\n *\n * This exists so that the same API can be used from both the browser\n * extension AND the plugin version of Turbo Admin.\n *\n * Note that for the extension, data saved is \"global\" to the extension\n * and is NOT site specific.\n */\nexport default class Storage {\n\n    /**\n     * Constructor - detects where code is running and sets the local\n     * store appropriately.\n     */\n    constructor() {\n        /** @type {null|storageStorageArea|WindowLocalStorage} */\n        this.store = null;\n\n        if ('undefined' === typeof (browser)) {\n            this.store = window.localStorage;\n        } else {\n            this.store = browser.storage.local;\n        }\n    }\n\n    /**\n     * Set/save extension data. Must be passed an object with key/value\n     * pairs.\n     *\n     * @param {Object} dataObject\n     */\n    async set(dataObject) {\n        if ('undefined' === typeof (browser)) {\n            const keys = Object.keys(dataObject);\n            keys.forEach(key => this.store.setItem(key, JSON.stringify(dataObject[key])));\n        } else {\n            await this.store.set(dataObject);\n        }\n    }\n\n    /**\n     * Get data from the extension's storage.\n     *\n     * Note that fetched data will be a object with the key as a\n     * property.\n     *\n     * @param {String} key\n     * @returns {Promise<Object>}\n     */\n    async get(key) {\n        if ('undefined' === typeof (browser)) {\n            let returnObj = {};\n            let item = this.store.getItem(key);\n            if (! item) {\n                return returnObj;\n            }\n            let itemObject = null;\n            try {\n                itemObject = JSON.parse(this.store.getItem(key));\n            } catch (e) {\n                itemObject = null;\n            }\n            returnObj[key] = itemObject;\n            return returnObj;\n        } else {\n            return await this.store.get(key);\n        }\n    }\n\n}\n", "import Storage from '../class-storage.js';\n\nexport default class ContentApi {\n\n    constructor() {\n        // this.discoverApiRoot().then(e => null);\n        // console.log('Discovered API base: ', this.apiBase);\n        this.active = false;\n        this.store = new Storage();\n        this.postTypes = [];\n\n        // This is used to \"cache\" duplicate requests.\n        // It's an object because it will have search strings as keys\n        this.cache = {};\n    }\n\n    async discoverApiRoot() {\n        console.log('Discovering API root');\n        let wpApiSettings = null;\n        this.storageKey = 'wpApiSettings.' + globalThis.taWp.home;\n\n        // Could be in the wp-api-request-js-extra (on wp-admin side)\n        const wpApiSettingsScript = document.getElementById('wp-api-request-js-extra');\n        if (wpApiSettingsScript) {\n            const wpApiSettingsString = wpApiSettingsScript.innerHTML.match(/var\\s+wpApiSettings\\s+=\\s+(.+);/)[1];\n            const wpApiSettings = JSON.parse(wpApiSettingsString);\n            const objectToSave = {};\n            objectToSave[this.storageKey] = wpApiSettings;\n            await this.store.set(objectToSave);\n            this.apiRoot = wpApiSettings.root;\n            this.apiBase = this.apiRoot + wpApiSettings.versionString;\n            this.apiNonce = wpApiSettings.nonce;\n            // Clear the nonce if one is set and we're not logged in\n            this.maybeExpireNonce(wpApiSettings);\n            this.active = true;\n            return;\n        }\n\n        // Getting from extension storage returns a object with the key\n        // as the key. Which is weird.\n        wpApiSettings = await this.store.get(this.storageKey);\n        if (wpApiSettings\n            && Object.keys(wpApiSettings).length !== 0\n            && wpApiSettings[this.storageKey]\n            && 'object' === typeof(wpApiSettings[this.storageKey])) {\n            // Get the key'ed item out of the object\n            wpApiSettings = wpApiSettings[this.storageKey];\n            this.apiRoot = wpApiSettings.root;\n            this.apiBase = this.apiRoot + wpApiSettings.versionString;\n            this.apiNonce = wpApiSettings.nonce;\n            // Clear the nonce if one is set and we're not logged in\n            this.maybeExpireNonce(wpApiSettings);\n            this.active = true;\n            return;\n        }\n\n        // Could be in <link rel=\"https://api.w.org/\" href=\"https://something/wp-json/\">\n        if (globalThis.taWp.apiLinkUrl) {\n            this.apiRoot = globalThis.taWp.apiLinkUrl;\n            // Just guess this\n            this.apiBase = this.apiRoot + 'wp/v2/';\n            this.active = true;\n            return;\n        }\n        // This should be very rare. I should only really see it in development.\n        console.log('API Route Discovery failed');\n        // TODO: This can't display as the palette isn't created yet.\n        // globalThis.turboAdmin.turboAdminPalette.showPaletteNotice('Can\\'t find the WP API. Try visiting the dashboard to refresh things.');\n    }\n\n    async discoverPostTypes() {\n        console.log('Discovering post types');\n        if (! this.active) {\n            console.log('Not active');\n            this.postTypes = [];\n            return;\n        }\n\n        this.postTypes = await this.getPostTypes();\n        console.log('Discovered post types: ', this.postTypes);\n    }\n\n    userLoggedIn() {\n        return document.body.classList.contains('logged-in') ||\n            document.body.classList.contains('wp-admin');\n    }\n\n    async maybeExpireNonce(wpApiSettings) {\n        if (wpApiSettings?.nonce && ! this.userLoggedIn()) {\n            // Clear apiSetting nonce\n            this.apiNonce = null;\n            wpApiSettings.nonce = null;\n            const objectToSave = {};\n            objectToSave[this.storageKey] = wpApiSettings;\n            await this.store.set(objectToSave);\n        }\n    }\n\n    makeParamString(data) {\n        const params = new URLSearchParams();\n\n        Object.keys(data).forEach(paramKey => {\n            // Handle arrays\n            if (Array.isArray(data[paramKey])) {\n                const arrayParamKey = paramKey + '[]';\n                data[paramKey].forEach( item => params.append(arrayParamKey, item));\n            } else {\n                params.append(paramKey, data[paramKey]);\n            }\n        });\n\n        return params.toString();\n    }\n\n    statuses() {\n        if (this.apiNonce) {\n            return [\"publish\", \"future\", \"draft\", \"pending\", \"private\"];\n        } else {\n            return [\"publish\"];\n        }\n    }\n\n    async getPostTypes() {\n        // Check the cache\n        if (undefined !== this.cache['postsTypes']) {\n            return this.cache['postTypes'];\n        }\n\n        // Fetch results\n        const response = await this.get('types');\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['postTypes'] = result;\n\n        return result;\n    }\n\n    async getPosts(searchString, postType = 'any') {\n        // Check the cache\n        const cacheKey =  `posts-${postType}-${searchString}`;\n        if (undefined !== this.cache[cacheKey]) {\n            return this.cache[cacheKey];\n        }\n\n        // Fetch results\n        const response = await this.get(\n            // \"posts\",\n            \"search\",\n            {\n                search: searchString,\n                per_page: 100,\n                // status: this.statuses(),\n                type: 'post',\n                subtype: postType\n            }\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache[cacheKey] = result;\n\n        return result;\n    }\n\n    /**\n     * We can't use the API to get a post of any post type. So we hack this a bit.\n     *\n     * @param {number} postId\n     * @returns {Promise<any>}\n     */\n    async doesPostExist(postId) {\n        // Check the cache\n        if (undefined !== this.cache['post-' + postId]) {\n            return this.cache['post-' + postId];\n        }\n\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n            credentials: 'include'\n        }\n\n        const response = await fetch(`${globalThis.taWp.siteUrl}/post.php?post=${postId}&action=edit`, init);\n\n        this.cache['post-' + postId] = response;\n\n        return response?.status === 200;\n    }\n\n    async getPlugins(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['plugins-' + searchString]) {\n            return this.cache['plugins-' + searchString];\n        }\n\n        let requestOptions = {};\n\n        if (searchString) {\n            requestOptions.search = searchString;\n        }\n\n        // Fetch results\n        const response = await this.get(\n            \"plugins\",\n            requestOptions\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['plugins-' + searchString] = result;\n\n        return result;\n    }\n\n    async getUsers(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['users-' + searchString]) {\n            return this.cache['users-' + searchString];\n        }\n\n        // Fetch results\n        const response = await this.get(\n            \"users\",\n            {\n                search: searchString,\n                per_page: 100,\n                context: 'edit' // view / embed / edit\n            }\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['users-' + searchString] = result;\n\n        return result;\n    }\n\n    async get(path, data = {}) {\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n            credentials: 'include'\n        }\n\n        // Add the nonce if there is one\n        if (this.apiNonce) {\n            data._wpnonce = this.apiNonce;\n        }\n\n        const params = this.makeParamString(data);\n\n        const response = await fetch(`${this.apiBase}${path}/?${params}`, init);\n\n        if (response.status < 200 || response.status >= 300) {\n            globalThis.turboAdmin.turboAdminPalette.showPaletteNotice('WordPress API Error. Try visiting the dashboard to refresh things.');\n        }\n\n        return response;\n    }\n\n}\n", "export default class SubmenuItem {\n    /**\n     * The title of the item\n     *\n     * @type {string}\n     */\n    title;\n\n    /**\n     * The URL of the item\n     * @type {string}\n     */\n    url;\n\n    /**\n     * A list of attributes to go on the A tag (not the LI tag)\n     *\n     * @type {array}\n     */\n    attributes = [];\n\n    /**\n     * Create a submenu item\n     *\n     * @param {string} title The title of the item\n     * @param {string} url The URL of the item\n     */\n    constructor(title, url) {\n        this.title = title;\n        this.url = url;\n    }\n\n    /**\n     * Add an attribute\n     *\n     * @param {string} name The attribute name\n     * @param {string} value The attribute value\n     */\n    addAttribute(name, value) {\n        this.attributes.push({\n            name: name,\n            value: value\n        });\n    }\n}\n", "import SubmenuItem from \"./class-submenu-item\";\n\nexport default class ContentItem {\n    /**\n     * The title of the item\n     *\n     * @type {string}\n     */\n    title = '';\n\n    /**\n     * The subtype of the item. e.g. for posts, this will be the post type.\n     * Used to display extra information about the item.\n     *\n     * @type {string}\n     */\n    subtype = '';\n\n    /**\n     * The URL of the item. Leave empty if there is a sub-menu.\n     *\n     * @type {string}\n     */\n    url = '';\n\n    /**\n     * The sub-menu items, if any.\n     *\n     * This should be an empty array if the item itself has a URL\n     *\n     * @type {SubmenuItem[]}\n     */\n    submenuItems = [];\n}\n", "import ContentItem from \"./class-content-item\";\n\nexport default class SearchMode {\n    /**\n     * The keyword string used to initiate the search\n     *\n     * @type {string}\n     */\n    keyword = '';\n\n    /**\n     * The dispay name used for the search\n     *\n     * @type {string}\n     */\n    displayName = '';\n\n    /**\n     * jsDoc defintion for a `searchCallback`\n     *\n     * @callback SearchCallback\n     * @param {string} [searchString]\n     * @returns {Promise<ContentItem[]>}\n     */\n\n    /**\n     * Callback to get search items\n     *\n     * @type {SearchCallback}\n     */\n    searchCallback;\n\n    /**\n     * Callback to get default items when entering a search mode\n     *\n     * @type {SearchCallback|null}\n     */\n    defaultItemsCallback = null;\n\n    /**\n     * Constructs a new search mode\n     *\n     * @param {string} keyword\n     * @param {string} displayName\n     * @param {SearchCallback} searchCallback\n     * @param {SearchCallback} defaultItemsCallback\n     */\n    constructor(keyword, displayName, searchCallback, defaultItemsCallback = null) {\n        this.keyword = keyword;\n        this.displayName = displayName;\n        this.searchCallback = searchCallback;\n        this.defaultItemsCallback = defaultItemsCallback;\n    }\n}\n", "/**\n * An item definition specifies how to detect a palette item from the Dashboard's Dom\n *\n * These are all processed on initialisation to generate menu items.\n *\n * Note that a single definition may generate multiple menu items if the selectors used\n * discover multiple items.\n */\nexport default class ItemDefinition {\n    /**\n     * This callback is displayed as part of the Requester class.\n    * @callback menuItemCallback\n    * @param {HTMLElement} element\n    * @returns {string}\n    */\n\n    /**\n     * The method of detecting items. Can be:\n     *  - 'dom' for checking if a DOM element exists (requires detectSelector or detectSelectorNone)\n     *  - 'url' if the current URL is being checked (requires detectPattern)\n     *\n     * @type {string}\n     */\n    detectType = 'dom';\n\n    /**\n     * [OPTIONAL] A CSS selector used to find items in the DOM\n     *\n     * @type {string}\n     */\n    detectSelector = '';\n\n    /**\n     * [OPTIONAL] A CSS selector used to check for an absence of items in the DOM\n     *\n     * @type {string}\n     */\n    detectSelectorNone = '';\n\n    /**\n     * A callback used to generate a menu item title from a detected element. Should be passed an\n     * HTML element and should return a string\n     *\n     * @type {menuItemCallback|null}\n     */\n     itemTitleFunction = null;\n\n    /**\n     * A callback used to generate a menu item link URL from a detected element. Should be passed an\n     * HTML element and should return a string\n     *\n     * @type {menuItemCallback|null}\n     */\n     itemUrlFunction = null;\n\n     /**\n      * True if the item is not to be cached. Used for things like post-specific links like \"Edit post\"\n      *\n      * @type {boolean}\n      */\n     noCache = false;\n}\n", "import SearchMode from \"./class-search-mode\";\nimport ItemDefinition from \"./class-item-definition\";\n\n/**\n * This is an abstract class that should be extended by plugins\n * @module TurboAdminPlugin\n */\nexport default class TurboAdminPlugin {\n    /** @type {string} */\n    name = '';\n\n    /** @type {SearchMode[]} */\n    searchModes = [];\n\n    /** @type {boolean} */\n    activated = false;\n\n    constructor(pluginName) {\n        this.name = pluginName;\n        this.registerPlugin();\n    }\n\n    /**\n     * Register the plugin with Turbo Admin\n     */\n    registerPlugin() {\n        console.log('Inside plugin - requested registration of ' + this.name);\n        globalThis.turboAdmin.registerPlugin(this);\n    }\n\n    /**\n     * Returns true if the plugin should activate\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        return false;\n    }\n\n    /**\n     * Activates the plugin\n     * @return {void}\n     */\n    activate() {\n        this.activated = true;\n        this.registerSearchModes();\n    }\n\n    /**\n     * Register the search keywords with Turbo Admin - each will be registered\n     * with the whole plugin object.\n     */\n    registerSearchModes() {\n        this.searchModes.forEach(globalThis.turboAdmin.registerSearchMode);\n    }\n\n    /**\n     * Get additional menu items to be added to the main menu\n     *\n     * @return {ItemDefinition[]}\n     */\n    getAdditionalItemDefinitions() {\n        return [];\n    }\n\n    /**\n     * Save plugin setting to persistent storage\n     */\n    saveSetting(key, value) {\n\n    }\n\n}\n", "export default class TurboAdminWpNotices {\n\n    // TODO: Handle empty IDS. Can we identify unique selectors?\n    // See spinup!\n    // Also need to only show move to panel if we can (i.e. if there's a way\n    // to identify it))\n    constructor(rememberedNoticeIds) {\n\n        // Bail if we aren't in the admin\n        if (! document.querySelector('body.wp-admin')) {\n            return;\n        }\n\n        /*\n        * These are the global notice selectors\n        */\n        this.noticeSelectors = [\n            '#wpbody-content > .notice',\n            '#wpbody-content > .wrap > .notice',\n            '#wpbody-content > .wrap > .updated',\n            '#gf_dashboard_message', // Gravity forms\n            '.jitm-banner', //\n            '.fs-notice', // I get this in Replyable\n            '#updraft-dashnotice', // Updraft backups\n            '.woocommerce-message', // WooCommerce\n            '#akismet_setup_prompt', // Akismet\n            '#wf-onboarding-plugin-header', // WordFence onboard\n            '.llar-notice-review' // Limit Login Attempts reloaded\n        ];\n\n        /*\n         * These selectors are allowed (unless explicitly denied)\n         */\n        this.allowedClasses = [\n            'notice-success',\n            'notice-error',\n            'notice-failure',\n            'updated',\n        ]\n\n        if (rememberedNoticeIds) {\n            this.rememberedNoticeIds = rememberedNoticeIds.length > 0 ? rememberedNoticeIds : [];\n        } else {\n            this.rememberedNoticeIds = [];\n        }\n\n        const toolbar = document.getElementById('wpadminbar');\n\n        if (!toolbar) {\n            return;\n        }\n\n        if (rememberedNoticeIds && rememberedNoticeIds.length > 0) {\n            rememberedNoticeIds.forEach(id => {\n                if ('string' === typeof(id) && id.length > 0) {\n                    this.noticeSelectors.push('#' + id);\n                }\n            });\n        }\n\nconsole.log('Notice Selectors', this.noticeSelectors);\n        const notices = document.querySelectorAll(this.noticeSelectors.join(','));\nconsole.log('Notices', notices);\n\n        // Add buttons to notices that can be moved\n        notices.forEach(notice => {\n            this.maybeAddIdToNotice(notice)\n\n            if (this.keepNotice(notice)) {\n                const rememberButton = document.createElement('button');\n                rememberButton.classList.add('ta-remember-notice-button');\n                rememberButton.innerText = 'Move to panel';\n\n                const forgetButton = document.createElement('button');\n                forgetButton.classList.add('ta-forget-notice-button');\n                forgetButton.innerText = 'Move to dashboard';\n\n                notice.classList.add('ta-added-pos-relative');\n\n                notice.appendChild(rememberButton);\n                notice.appendChild(forgetButton);\n\n                rememberButton.addEventListener('click', this.rememberNotice.bind(this), false, true);\n                forgetButton.addEventListener('click', this.forgetNotice.bind(this), false, true);\n            }\n        });\n\n        const noticesToHide = Array.from(notices).filter(notice => {\n            if (this.rememberedNoticeIds.includes(notice.id)) {\n                return true;\n            }\n\n            if (this.keepNotice(notice)) {\n                return false;\n            }\n\n            // Invisible\n            if (\n                notice.offsetHeight === 0 ||\n                notice.offsetWidth === 0\n            ) {\n                return false;\n            }\n\n            return true;\n        })\n\n        console.log('Notices to hide', noticesToHide)\n\n        /**\n         * Build the notices wrapper\n         */\n        /** @type {HTMLDivElement} */\n        const noticesLinkWrapper = document.createElement('div');\n        noticesLinkWrapper.id = 'ta-notices-link-wrap';\n        noticesLinkWrapper.classList.add('hide-if-no-js', 'screen-meta-toggle');\n        noticesLinkWrapper.style.margin='0 0 0 6px';\n        noticesLinkWrapper.style.float='left';\n        if (noticesToHide.length === 0) {\n            noticesLinkWrapper.style.display='none';\n        }\n\n        /**\n         * Add button\n         */\n        /** @type {HTMLButtonElement} */\n        const noticesButton = document.createElement('button');\n        noticesButton.type='button';\n        noticesButton.id='ta-notices-link';\n        noticesButton.classList.add('button', 'show-settings');\n        noticesButton.innerHTML='Notices <span id=\"ta-notice-count\">' + noticesToHide.length + '</span>';\n        noticesButton.setAttribute('aria-controls', 'ta-notices-wrap');\n\n        // This should replicate the functionality from wp-admin/js/common.js\n        // as closely as possible. But note that we can't access the common.js\n        // functions.\n        noticesButton.addEventListener('click', this.toggleNoticesPanel.bind(this), false);\n\n        /**\n         * Add button to the link wrapper\n         */\n        noticesLinkWrapper.appendChild(noticesButton);\n\n        /**\n         * Add the link wrapper to the screen-meta-links section\n         */\n        const screenMetaLinks = document.getElementById('screen-meta-links');\n        screenMetaLinks.appendChild(noticesLinkWrapper);\n\n        /**\n         * Build the panel\n         */\n        const noticesPanel = document.createElement('div');\n\n        noticesPanel.id='ta-notices-wrap';\n        noticesPanel.style.display='none';\n        noticesPanel.dataset.open='no';\n\n        const noticesPanelInner = document.createElement('div');\n        noticesPanelInner.id = 'ta-notices-panel-inner';\n\n        noticesToHide.forEach(notice => {\n            // See Toolbelt's implementation: https://github.com/BinaryMoon/wp-toolbelt/blob/dev/modules/tidy-notifications/src/js/script.js\n            noticesPanelInner.append(notice);\n        });\n\n        /**\n         * Add wrap to the meta area\n         */\n        noticesPanel.appendChild(noticesPanelInner);\n        const screenMeta = document.getElementById('screen-meta');\n        screenMeta.appendChild(noticesPanel);\n\n        // Set up events on the new screen-meta item\n        // if (window.screenMeta) {\n        //     window.screenMeta.init();\n        // }\n    }\n\n    // Does the allowedClasses list say that this notice should be shown?\n    keepNotice(noticeElem) {\n        return this.allowedClasses.reduce( (found, current) => {\n            return found || noticeElem.classList.contains(current)\n        }, false);\n    }\n\n    rememberNotice(ev) {\n        const noticesLinkWrap = document.getElementById('ta-notices-link-wrap');\n        const panel = document.getElementById('wp-admin-bar-ta-notices');\n        const panelInner = document.getElementById('ta-notices-panel-inner');\n        const countElem = document.getElementById('ta-notice-count');\n        const count = parseInt(countElem.innerText, 10);\n        const notice = ev.target.closest(this.noticeSelectors.join(','));\n        const noticeId = notice.id;\n        console.log(`Remembering ${noticeId}`);\n        panelInner.appendChild(notice);\n        if (count === 0) {\n            noticesLinkWrap.style.display = 'block';\n        }\n\n        this.updateScreenMetaHeight();\n\n        countElem.innerText = parseInt(countElem.innerText, 10) + 1;\n\n        this.saveRememberedNotice(noticeId);\n    }\n\n    saveRememberedNotice(noticeId) {\n        this.rememberedNoticeIds.push(noticeId);\n\n        if ('object' === typeof(browser)) {\n            browser.runtime.sendMessage({\n                'action': 'rememberNotice',\n                'noticeId': noticeId,\n            });\n        } else {\n            window.localStorage.setItem('rememberedNoticeIds', JSON.stringify(this.rememberedNoticeIds));\n        }\n    }\n\n    forgetNotice(ev) {\n        const noticesLinkWrap = document.getElementById('ta-notices-link-wrap');\n        const panelInner = document.getElementById('ta-notices-panel-inner');\n        const countElem = document.getElementById('ta-notice-count');\n        const count = parseInt(countElem.innerText, 10);\n        const notice = ev.target.closest(this.noticeSelectors.join(','));\n        const noticeId = notice.id;\n        console.log(`Forgetting ${noticeId}`);\n\n        notice.remove();\n\n        const message = document.createElement('div');\n        const p = document.createElement('p');\n        message.classList.add('notice', 'ta-forget-notice-message');\n        p.textContent = 'Notice will be back in dashboard on next page load';\n        message.appendChild(p);\n        panelInner.appendChild(message);\n\n        this.updateScreenMetaHeight();\n\n        // I was going to to this, but we need to keep the notice about\n        // where the notice has gone.\n        // if (count === 1) {\n        //     noticesLinkWrap.style.display = 'none';\n        // }\n\n        countElem.innerText = (count - 1).toString();\n        this.saveForgottenNotice(noticeId);\n    }\n\n    saveForgottenNotice(noticeId) {\n        this.rememberedNoticeIds.push(noticeId);\n\n        if ('object' === typeof(browser)) {\n            browser.runtime.sendMessage({\n                'action': 'rememberNotice',\n                'noticeId': noticeId,\n            });\n        } else {\n            this.rememberedNoticeIds = this.rememberedNoticeIds.filter( id => id !== noticeId );\n            window.localStorage.setItem('rememberedNoticeIds', JSON.stringify(this.rememberedNoticeIds));\n        }\n    }\n\n    /*\n     * For notices without IDs we'll see if we can add an ID that's a hash of their classlist\n     */\n    maybeAddIdToNotice(notice) {\n        if (notice.id && notice.id !== '' && notice.id !=='message') {\n            return;\n        }\n\n        const classes = notice.classList;\n        notice.id = Array.from(notice.classList).join('-');\n    }\n\n    /**\n     * Detect if WordPress has already applied event handlers to our new screen meta button.\n     *\n     * If it has then WordPress/backbone.js will handle the animation and we won't have to.\n     *\n     * @returns {boolean}\n     */\n    wordpressScreenMetaEventsExist() {\n        return 'object' === typeof(window.screenMeta) && window.screenMeta.toggles.filter('#ta-notices-link').length > 0;\n    }\n\n    updateScreenMetaHeight() {\n        // Don't do this if we're relying on backbone's animation\n        if (this.wordpressScreenMetaEventsExist()) {\n            return;\n        }\n\n        const screenMeta = document.getElementById('screen-meta');\n        const noticesPanel = document.getElementById('ta-notices-wrap');\n        const height = noticesPanel.offsetHeight;\n        screenMeta.style.maxHeight = height.toString(10) + 'px';\n    }\n\n    toggleNoticesPanel(ev) {\n        // We may be in the plugin in which case we don't want to run our handler if there's\n        // a backbone handler on the button.\n        if (this.wordpressScreenMetaEventsExist()) {\n            return;\n        }\n        // Otherwise we mimic the swipe down animation.\n        const animationSeconds = 0.3;\n        const screenMeta = document.getElementById('screen-meta');\n        const noticesPanel = document.getElementById('ta-notices-wrap');\n        if (noticesPanel.dataset.open === 'no') {\n            this.toggleOtherScreenMetaTabs();\n            // Don't ask... just DON'T ask!\n            noticesPanel.dataset.open = 'yes';\n            screenMeta.style.transition = `max-height ${animationSeconds.toString(10)}s`;\n            screenMeta.style.maxHeight = '0';\n            screenMeta.style.overflow = 'hidden';\n            screenMeta.style.display = 'block';\n            noticesPanel.style.display = 'block';\n            const height = noticesPanel.offsetHeight;\n            screenMeta.style.maxHeight = height.toString(10) + 'px';\n            // setTimeout(() => {\n            //     // Nothing to do here.\n            // }, animationSeconds * 1000);\n        } else {\n            noticesPanel.dataset.open = 'no';\n            const height = noticesPanel.offsetHeight;\n            screenMeta.style.maxHeight = '0';\n            setTimeout(() => {\n                noticesPanel.style.display = '';\n                screenMeta.style.display = '';\n                screenMeta.style.transition = '';\n                screenMeta.style.overflow = '';\n                screenMeta.style.maxHeight = '';\n                this.toggleOtherScreenMetaTabs();\n            }, animationSeconds * 1000);\n        }\n\n    }\n\n    toggleOtherScreenMetaTabs() {\n        const otherTabs = document.querySelectorAll('#screen-meta-links .screen-meta-toggle:not(#ta-notices-link-wrap)');\n        otherTabs.forEach( (tab) => {\n            if (tab.style.visibility === 'hidden') {\n                tab.style.visibility = '';\n            } else {\n                tab.style.visibility = 'hidden';\n            }\n        } );\n    }\n}\n", "export default class ListTableShortcuts {\n\n    constructor() {\n        /**\n         * @type {ListTableShortcuts}\n         */\n        const me = this;\n\n        /**\n         * @type {null|HTMLElement}\n         */\n        this.currentRow = null;\n\n        /**\n         * @type {number}\n         */\n        this.currentRowIndex = 0;\n\n        /**\n         * @type {HTMLTableElement}\n         */\n        this.listTable = document.querySelector('.wp-list-table');\n\n        if (! this.listTable) {\n            return;\n        }\n\n        /**\n         * @type {NodeListOf<HTMLTableRowElement>}\n         */\n        this.tableRows = this.listTable.querySelectorAll('tbody#the-list > tr');\n\n        document.addEventListener('keyup', e => this.handleKeyup(e));\n    }\n\n    /**\n     *\n     * @param {KeyboardEvent} ev\n     */\n    handleKeyup(ev) {\n        if (document.activeElement.tagName !== 'BODY') {\n            return;\n        }\n\n        if (ev.key === 'j') {\n            this.tableMoveDown();\n        } else if (ev.key === 'k') {\n            this.tableMoveUp();\n        } else if (ev.key.toLowerCase() === 'enter' && this.currentRow !== null) {\n            this.openTableRowItem();\n        }\n\n    }\n\n    tableMoveDown() {\n        this.preTableChange();\n\n        // Move down\n        if (this.currentRow === null) {\n            this.currentRowIndex = 0;\n        } else {\n            this.currentRowIndex++;\n        }\n        this.updateTable();\n    }\n\n    tableMoveUp() {\n        this.preTableChange();\n\n        if (this.currentRowIndex > 0) {\n            this.currentRowIndex--;\n            this.updateTable();\n        }\n    }\n\n    preTableChange() {\n        if (this.currentRow !== null) {\n            this.tableRows[this.currentRowIndex].classList.remove('ta-active-table-row');\n        }\n    }\n\n    updateTable() {\n        this.currentRow = this.tableRows[this.currentRowIndex];\n\n        if (! this.tableRows[this.currentRowIndex].classList.contains('ta-active-table-row')) {\n            this.tableRows[this.currentRowIndex].classList.add('ta-active-table-row');\n        }\n    }\n\n    openTableRowItem() {\n        console.log(this);\n        /** @type {HTMLAnchorElement} */\n        const link = this.currentRow.querySelector('a.row-title');\n        if (link) {\n            link.click();\n        }\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\n\nexport default class TurboAdminBarkeeper extends TurboAdminPlugin {\n    constructor() {\n        super('Barkeeper');\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        if (true !== globalThis.turboAdmin.options['barkeeper']) {\n            return false;\n        }\n        // Bail if we aren't in the admin\n        if (! document.getElementById('wpadminbar')) {\n            return false;\n        }\n        return true;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n\n        this.exclusionIds = [\n            'wp-admin-bar-menu-toggle',\n            'wp-admin-bar-wp-logo',\n            'wp-admin-bar-site-name',\n            'wp-admin-bar-updates',\n        ];\n\n        this.barkeeperState = globalThis.turboAdmin.options['barkeeper-state'];\n\n        this.root = document.getElementById('wp-admin-bar-root-default');\n        this.itemsToHide = document.querySelectorAll( '#wp-admin-bar-root-default > li');\n\n        Array.from(this.itemsToHide).forEach( element => {\n            if (this.exclusionIds.includes(element.id)) {\n                return;\n            }\n            element.classList.add('ta-barkeeper-collapsable');\n        });\n\n        if (this.barkeeperState === 'closed') {\n            this.root.classList.toggle('ta-barkeeper-closed');\n        }\n\n        // Add toggle\n        this.button = document.createElement('button');\n        this.button.id = 'ta-barkeeper-toggle';\n        this.button.innerText = '<';\n\n        this.button.addEventListener('click', e => {\n            this.root.classList.toggle('ta-barkeeper-closed');\n\n            this.barkeeperState = this.barkeeperState === 'open' ? 'closed' : 'open';\n\n            browser.runtime.sendMessage({\n                'action': 'barkeeperSetState',\n                'barkeeperState': this.barkeeperState,\n            });\n        });\n\n        this.root.insertAdjacentElement('afterend', this.button);\n    }\n\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminContentSearch extends TurboAdminPlugin {\n    constructor() {\n        super('WP Content');\n\n        // Register a search mode for each post type\n        const postTypeKeys = Object.keys(globalThis.contentApi.postTypes);\n        for (let i = 0; i < postTypeKeys.length; i++) {\n            const thisPostTypeKey = postTypeKeys[i];\n            const thisPostType = globalThis.contentApi.postTypes[thisPostTypeKey];\n            // console.log('Adding search mode for post type', thisPostType);\n            this.searchModes.push( this.makePostTypeSearchMode(thisPostType) );\n        }\n\n        // Register ID search mode\n        this.searchModes.push( new SearchMode('id', 'Post ID', this.postById.bind(this)) );\n\n        // Register search all post types mode\n        this.searchModes.push( new SearchMode('search', 'All post types', this.contentSearch.bind(this)) );\n        this.searchModes.push( new SearchMode('find', 'All post types', this.contentSearch.bind(this)) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // TODO: Is this right? Should we check for API access?\n        return true;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * This is a generator for a post-type specific SearchMode object\n     *\n     * @param {Object} postType\n     */\n    makePostTypeSearchMode(postType) {\n        // TODO: interpret the post type name\n        return new SearchMode(postType.slug, postType.name, (searchString) => this.contentSearch(searchString, postType.slug));\n    }\n\n    /**\n     * @param {string} searchString\n     * @param {string} postType This is passed to the API as a subtype. 'any' by default.\n     * @returns {Promise<ContentItem[]>}\n     */\n    async contentSearch(searchString, postType = 'any') {\n        /**\n         * Possible actual code\n         */\n        const results = await globalThis.contentApi.getPosts(searchString, postType);\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            const item = new ContentItem;\n                            item.title = result.title;\n                            item.subtype = result.subtype;\n                            item.url = result.url;\n\n                            item.submenuItems = item.submenuItems.concat(this.makeSubmenuItems(result.id, item))\n\n                            return item;\n                        });\n    }\n\n    /**\n     * @param {string} postId\n     * @returns {Promise<ContentItem[]>}\n     */\n    async postById(postId) {\n        if (! postId.trim().match(/^\\d+$/)) {\n            return [];\n        }\n        const postExists = await globalThis.contentApi.doesPostExist(postId);\n\n        const resultAsContentItem = new ContentItem;\n\n        if (! postExists) {\n            resultAsContentItem.title = 'Post does not exist or is not visible';\n            return [ resultAsContentItem ];\n        }\n\n        resultAsContentItem.title = `Post ID: ${postId}`;\n        resultAsContentItem.url = globalThis.taWp.home + `/?p=${postId}`;\n\n        resultAsContentItem.submenuItems = resultAsContentItem.submenuItems.concat(this.makeSubmenuItems(postId, resultAsContentItem));\n\n        return [ resultAsContentItem ];\n    }\n\n    /**\n     * Makes an array of submenu items from a content item\n     *\n     * @param {number} postId\n     * @param {ContentItem} contentItem\n     * @returns {SubmenuItem[]}\n      */\n    makeSubmenuItems(postId, contentItem) {\n        const itemsToReturn = [];\n        itemsToReturn.push(\n            new SubmenuItem(\n                'View',\n                contentItem.url\n            )\n        );\n\n        // TODO: Make a better way to detect if we are logged in.\n        if (globalThis.turboAdmin.turboAdminPalette.profileLink) {\n            // Need to get edit URL. This seems like the best way for now.\n            const editLink = globalThis.taWp.siteUrl + `/post.php?post=${postId}&action=edit`;\n            itemsToReturn.push(\n                new SubmenuItem(\n                    'Edit',\n                    editLink\n                )\n            )\n\n            // Add oxygen link if needed.\n            if (globalThis.turboAdmin.hasActivatedPlugin('OxygenBuilder')) {\n                const oxygenLink = globalThis.taWp.home + `?page_id=${postId}&ct_builder=true&ct_inner=true`;\n                itemsToReturn.push(\n                    new SubmenuItem(\n                        'Edit with Oxygen',\n                        oxygenLink\n                    )\n                );\n            }\n        }\n\n        const copyLinkItem = new SubmenuItem( 'Copy link', contentItem.url);\n        copyLinkItem.addAttribute('data-action', 'clipboard')\n        itemsToReturn.push(copyLinkItem);\n\n        return itemsToReturn;\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminPluginSearch extends TurboAdminPlugin {\n    constructor() {\n        super('WP Plugins');\n\n        this.searchModes.push( new SearchMode('plugin', 'Plugins', this.pluginSearch, this.defaultPluginItems.bind(this)) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // TODO: Is this right? Should we check for API access?\n        return true;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * Callback to get default items when entering a search mode\n     *\n     * @returns {Promise<ContentItem[]>}\n     */\n    async defaultPluginItems() {\n        return await this.pluginSearch('');\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async pluginSearch(searchString) {\n        /**\n         * Possible actual code\n         */\n        const results = await globalThis.contentApi.getPlugins(searchString);\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            // siteUrl is at globalThis.turboAdmin.wp.siteUrl\n                            const item = new ContentItem;\n                            item.title = result.name;\n                            item.subtype = 'Plugin';\n                            // TODO: Maybe set this to be a search on the plugin screen?\n                            // Plugin \"slug\" is in result.name\n\n                            const itemViewUrlParams = new URLSearchParams();\n                            itemViewUrlParams.set('plugin_status', 'all');\n                            itemViewUrlParams.set('s', result.name);\n                            item.submenuItems.push(\n                                new SubmenuItem(\n                                    'View',\n                                    globalThis.taWp.siteUrl + '/plugins.php?' + itemViewUrlParams.toString()\n                                )\n                            );\n                            // Activate: /wp-admin/plugins.php?action=activate&plugin=order-simulator-woocommerce%2Fwoocommerce-order-simulator.php&plugin_status=all&paged=1&s&_wpnonce=3714a01759\n\n                            return item;\n                        });\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\n\nexport default class TurboAdminUserSearch extends TurboAdminPlugin {\n    constructor() {\n        super('WP Users');\n\n        this.searchModes.push( new SearchMode('user', 'Users', this.userSearch, this.defaultUserItems.bind(this)) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // TODO: Is this right? Should we check for API access?\n        return true;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * Callback to get default items when entering a search mode\n     *\n     * @returns {Promise<ContentItem[]>}\n     */\n     async defaultUserItems() {\n        return await this.userSearch('');\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async userSearch(searchString) {\n        /**\n         * Possible actual code\n         */\n        const results = await globalThis.contentApi.getUsers(searchString);\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            const item = new ContentItem;\n                            if (result.first_name && result.last_name) {\n                                item.title = `${result.first_name} ${result.last_name} - `;\n                            }\n                            item.title += result.email;\n                            item.subtype = result.roles[0];\n                            item.url = globalThis.taWp.siteUrl + `/user-edit.php?user_id=${result.id}`;\n                            return item;\n                        });\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminMUSites extends TurboAdminPlugin {\n    constructor() {\n        super('WP Multisite Sites');\n\n        this.searchModes.push( new SearchMode('site', 'Sites', this.siteSearch.bind(this), this.defaultSiteItems.bind(this)) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        return Boolean(document.querySelector('#wp-admin-bar-my-sites'));\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * Callback to get default items when entering a search mode\n     *\n     * @returns {Promise<ContentItem[]>}\n     */\n     async defaultSiteItems() {\n        return await this.siteSearch('');\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async siteSearch(searchString) {\n        // {\n        //     'detectType': 'dom',\n        //     'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-my-sites-list .ab-submenu a',\n        //     'itemTitleFunction': (element) => \"Sites: \" + element.closest('.menupop').querySelector('a').innerText + ' - ' + element.innerText,\n        //     'itemUrlFunction': (element) => element.href\n        // },\n\n        const sites = document.querySelectorAll('#wp-admin-bar-my-sites #wp-admin-bar-my-sites-list > li');\n\n        if (sites.length === 0) {\n            return [];\n        }\n\n        const sitesArray = Array.from(sites);\n        const sitesLinks = sitesArray.map(site => site.querySelector('a'));\n        const filteredSites = sitesLinks.filter(site => site.innerText.toLowerCase().includes(searchString.toLowerCase()));\n\n        return filteredSites.map(site => {\n            const item = new ContentItem;\n            item.title = site.innerText;\n            item.subtype = 'Site';\n            item.url = site.href;\n\n            item.submenuItems = item.submenuItems.concat(this.makeSubmenuItems(site));\n\n            return item;\n        });\n    }\n\n    makeSubmenuItems(siteElement) {\n        const submenuItems = [];\n\n        const submenu = siteElement.nextElementSibling.querySelector(`.ab-submenu`);\n        if (! submenu) {\n            return [];\n        }\n\n        const submenuLinks = submenu.querySelectorAll('a');\n        if (submenuLinks.length === 0) {\n            return [];\n        }\n\n        const submenuLinksArray = Array.from(submenuLinks);\n        submenuLinksArray.forEach(link => {\n            const submenuItem = new SubmenuItem(link.innerText, link.href);\n            submenuItems.push(submenuItem);\n        });\n\n        return submenuItems;\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\nimport ItemDefinition from '../types/class-item-definition.js';\n\nexport default class TurboAdminOxygenBuilder extends TurboAdminPlugin {\n    constructor() {\n        super('OxygenBuilder');\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // Check for presence of Oxygen Page builder\n        /** @type {HTMLElement|string|Number} */\n        let oxygenLinkElem = document.getElementById('toplevel_page_ct_dashboard_page');\n        // Also check for a menu bar item\n        if (! oxygenLinkElem) {\n            oxygenLinkElem = document.getElementById('wp-admin-bar-oxygen_admin_bar_menu');\n        }\n        // Check to see if Oxygen link is cached\n        if (! oxygenLinkElem) {\n            oxygenLinkElem = Number(window.localStorage.getItem('ta-has-oxygen-builder'));\n        }\n\n        const hasOxygenBuilder = Boolean(oxygenLinkElem);\n\n        // Save Oxygen builder status\n        window.localStorage.setItem('ta-has-oxygen-builder', hasOxygenBuilder ? '1' : '0' );\n\n        return hasOxygenBuilder;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * Get additional menu items to be added to the main menu\n     *\n     * @return {ItemDefinition[]}\n     */\n     getAdditionalItemDefinitions() {\n        const editDefinition = new ItemDefinition();\n        editDefinition.detectType = 'dom';\n        editDefinition.detectSelector = '#ct-edit-template-builder';\n        editDefinition.itemTitleFunction = () => 'Edit with Oxygen';\n        editDefinition.itemUrlFunction = (element) => element.href;\n        editDefinition.noCache = true;\n\n        // It's worth noting that the Oxygen Builder doesn't use a /wp-admin URL\n        // and so kinda appears to Turbo Admin to be a \"front-end\" page and it\n        // doesn't refresh the menu items.\n        const backToWpDefinition = new ItemDefinition();\n        backToWpDefinition.detectType = 'dom';\n        backToWpDefinition.detectSelector = '.oxygen-back-to-wp-menu .oxygen-toolbar-button-dropdown a:not(:last-of-type)';\n        backToWpDefinition.itemTitleFunction = (element) => 'Back to WP: ' + element.textContent;\n        backToWpDefinition.itemUrlFunction = (element) => {\n            if (element.href) {\n                return element.href;\n            } else {\n                let url = new URL(window.location.href);\n                return url.origin + url.pathname;\n            }\n        };\n        backToWpDefinition.noCache = true;\n\n        return [\n            editDefinition,\n            backToWpDefinition,\n        ];\n    }\n\n}\n", "/*\n * This is the common Turbo Admin library.\n *\n * It's (currently) WordPress-specific, but can be loaded by\n * either the Extension OR the Plugin\n *\n * It takes an options object:\n *\n * options: {\n *   shortcutKeys: [\n *     // Array of shortcut key definitions, like:\n *     {\n *       {\n *         meta: false,\n *         alt: true,\n *         ctrl: true,\n *         shift: true,\n *         key: 'p'\n *       }\n *     }\n *   ],\n *   appendToElement {\n *     // Optional CSS selector to define what to append the palette to\n *     'body'\n *   },\n *   extraItems: [\n *     // Optional array of extra item configs used to generate new item objects\n *     {\n *       'detectType': 'url',\n *       'detectPattern': 'wp-login',\n *       'itemTitle': 'View/visit site',\n *       'itemUrlFunction': () => this.home\n *     },\n *   ],\n *   extraItemsRaw: [\n *     // Optional array of raw item objects to be added\n *     {\n *       'title': ,\n *       'action': ,\n *       'parentTitle': ,\n *     }\n *   ]\n * }\n */\n\nimport TurboAdminPalette from './class-turbo-admin-palette.js';\nimport TurboAdminMenuItem from './types/class-turbo-admin-menu-item.js';\nimport SearchMode from './types/class-search-mode.js';\nimport TurboAdminPlugin from './types/class-turbo-admin-plugin.js';\nimport Acf from './plugins/class-acf.js';\n// import TurboAdminWpBlockEditorFullscreenKill from './class-turbo-admin-wp-block-editor-fullscreen-kill.js';\n// import TurboAdminWpBlockEditorWelcomeGuideKill from './class-turbo-admin-wp-block-editor-welcome-guide-kill.js';\nimport TurboAdminWpNotices from './class-turbo-admin-wp-notices.js';\nimport TurboAdminListTableShortcuts from './class-list-table-shortcuts.js';\nimport TurboAdminBarkeeper from './plugins/class-turbo-admin-barkeeper.js';\nimport TurboAdminContentSearch from './plugins/class-turbo-admin-content-search.js';\nimport TurboAdminPluginSearch from './plugins/class-turbo-admin-plugins.js';\nimport TurboAdminUserSearch from './plugins/class-turbo-admin-users.js';\n// import TurboAdminWoocommerce from './plugins/class-turbo-admin-woocommerce.js';\n// import TurboAdminGravityForms from './plugins/class-turbo-admin-gravity-forms.js';\nimport TurboAdminMUSites from './plugins/class-turbo-admin-mu-sites.js';\nimport TurboAdminOxygenBuilder from './plugins/class-turbo-admin-oxygen-buillder.js';\n\nexport default class TurboAdmin {\n\n    /**\n     * @param {*} options\n     * @returns {TurboAdmin}\n     */\n    constructor(options) {\n        // Sometimes we get a second copy of TA running, like if the plugin is running too.\n        // Is this case we want to skip the initialisation.\n        this.doInit = true;\n\n        if (document.getElementById('ta-command-palette-container')) {\n            console.log('TurboAdmin already initialised - I won\\'t make a second copy!');\n            this.doInit = false;\n            return globalThis.turboAdmin;\n        }\n\n        this.options = options;\n        this.plugins = {};\n\n        // TODO: Something? What should this type be?\n        this.searchModes = {};\n\n        // On the front end we set this if there is no saved menu.\n        this.menuNeedsRefresh = false;\n    }\n\n    /**\n     * Perform initialization - this is all the things that do not need APIs to\n     * get set up.\n     */\n    async init() {\n        if (! this.doInit) {\n            return;\n        }\n\n        // Register all the plugins\n        new TurboAdminBarkeeper();\n        new TurboAdminContentSearch();\n        new TurboAdminPluginSearch();\n        new TurboAdminUserSearch();\n        // new TurboAdminWoocommerce();\n        // new TurboAdminGravityForms();\n        new TurboAdminMUSites();\n        new TurboAdminOxygenBuilder();\n\n        // Grab the global Wp object instance\n        this.wp = globalThis.taWp;\n\n        this.menu = [];\n\n        // Check for saved menu when on front-end\n        if (! this.wp.isBackend) {\n            // Only use the cached items if the current URL matches the last site URL\n            // This handles changes of multi-site site!\n            // We ONLY need to do this on the front-end as the back-end will always\n            // refresh the menu.\n            if (! this.wp.siteChanged) {\n                // Check for .logged-in class on body - if logged in, we can use the saved menu,\n                // if it exists.\n                if (document.body.classList.contains('logged-in')) {\n                    // Get from localStorage\n                    const savedMenu = window.localStorage.getItem('ta-palette-data');\n\n                    // This attempts to see if we have cached items from the back-en\n                    if (null === savedMenu) {\n                        this.menuNeedsRefresh = true;\n                    } else {\n                        this.menu = JSON.parse(savedMenu);\n                        // Check if there is no \"Media\" item  - this should ONLY be in the back-end\n                        if (! this.menu.some(item => item.action.endsWith('upload.php'))) {\n                            this.menuNeedsRefresh = true;\n                        }\n                        // Merge (?) the items?\n                    }\n                }\n            }\n        } else {\n            // On the back end, get the WordPress dashboard menu items\n            this.menu = this.getMenu();\n        }\n\n        // Add other additional items\n        this.addAdditionalMenuItems();\n        // Add items passed in using extraItemsRaw\n        this.menu = this.menu.concat(this.options.extraItemsRaw ?? []);\n\n        // Add ACF items?\n        // TODO: Make this better. Possible ASYNC somehow?\n        // this.acf = new Acf();\n        // if (this.acf.isAcfInstalled()) {\n        //     const acfLinks = await this.acf.getFieldGroups()\n        //     // console.table(acfItems);\n        //     const acfMenuItems = acfLinks.map(\n        //         item => new TurboAdminMenuItem(\n        //             item.label + ' (ACF)',\n        //             item.link,\n        //             ''\n        //         )\n        //     );\n        //     this.menu = this.menu.concat(acfMenuItems);\n        // }\n\n        // Sort the menu\n        this.menu.sort((a, b) => (a.parentTitle + a.title).localeCompare(b.parentTitle + b.title));\n\n        // Filter out no-cache items and save to localStorage.\n        const itemsToSave = this.menu.filter(item => (! item.noCache));\n        window.localStorage.setItem('ta-palette-data', JSON.stringify(itemsToSave));\n\n        // Add palette markup to the DOM\n        this.addPalette();\n        // Initialise controls on the palette\n        this.turboAdminPalette = new TurboAdminPalette(this.menu, this.options);\n    }\n\n    /**\n     * These are initialization steps that DO needs APIs to be set up.\n     */\n    activatePlugins() {\n        // Initialize all plugins\n        Object.keys(this.plugins).forEach( plugin => {\n            if (this.plugins[plugin].shouldActivate()) {\n                this.plugins[plugin].activate();\n            }\n        })\n\n        // if (true === this.options['block-editor-fullscreen-disable']) {\n        //     // Initialise fullscreen kill\n        //     this.turboAdminFullscreenKill = new TurboAdminWpBlockEditorFullscreenKill();\n        // }\n\n        // if (true === this.options['block-editor-welcome-screen-kill']) {\n        //     this.turboAdminWelcomeKill = new TurboAdminWpBlockEditorWelcomeGuideKill();\n        // }\n\n        if (true === this.options['list-table-keyboard-shortcuts']) {\n            this.turboAdminListTableShortcuts = new TurboAdminListTableShortcuts();\n        }\n\n        // Add other things if we're logged in and have an API nonce\n        if (globalThis.contentApi.userLoggedIn()) {\n            // What shall we do?\n        }\n    }\n\n    /**\n     * True if the plugin has been activated\n     *\n     * @param {string} name Name of the plugin to check for\n     * @returns {boolean}\n     */\n    hasActivatedPlugin(name) {\n        return Object.keys(this.plugins).includes(name) &&\n            this.plugins[name].activated;\n    }\n\n    /**\n     * Gather the WordPress dashboard admin (sidebar) menu items\n     *\n     * @returns { TurboAdminMenuItem[] }\n     */\n    getMenu() {\n        const items = [];\n        const menuTop = document.getElementById('adminmenu');\n        if (menuTop) {\n            const topDOMItems = menuTop.querySelectorAll('li.menu-top');\n            topDOMItems.forEach(el => {\n                const a = el.querySelector('a.menu-top');\n                const title = a.querySelector('.wp-menu-name').innerHTML;\n                const action = a.href;\n                const parentTitle = '';\n                const item = new TurboAdminMenuItem(title, action, parentTitle);\n                items.push(item);\n\n                const subMenu = el.querySelector('.wp-submenu');\n                if (!subMenu) {\n                    return;\n                }\n                const subItems = subMenu.querySelectorAll('li a');\n                if (!subItems) {\n                    return;\n                }\n                subItems.forEach(subEl => {\n                    const parentTitle = title;\n                    const childTitle = subEl.innerHTML;\n                    const childAction = subEl.href;\n                    const item = new TurboAdminMenuItem(childTitle, childAction, parentTitle);\n                    items.push(item);\n                })\n            });\n        }\n        return items;\n    }\n\n    /**\n     * Adds additional menu items passed in by configuration to the\n     * menu items list.\n     */\n    addAdditionalMenuItems() {\n\n        /*\n         * I'd LOVE for this to be config driven\n         *\n         * [\n         *   {\n         *     'detectType': 'url',\n         *     'detectPattern': 'wp-login',\n         *     'itemTitle': 'View/visit site',\n         *     'itemUrlFunction': () => this.home\n         *   },\n         *   {\n         *     'detectType': 'dom',\n         *     'detectSelector': '#wpadminbar',\n         *     'itemTitle': 'Logout',\n         *     'itemUrlFunction': () => logoutUrl\n         *   }\n         *  Can we add actionTypes as well? To do clicks and navigates?\n         * ]\n         */\n\n        // Get passed-in extraItems\n        // Technically this is an array of {ItemDefintion} but more work needed to make that happen.\n        let extraItems = this.options.extraItems ?? [];\n\n        // Get any extra items defined by plugins\n        const pluginKeys = Object.keys(this.plugins);\n\n        for (let i=0; i < pluginKeys.length; i++) {\n            extraItems = extraItems.concat(this.plugins[pluginKeys[i]].getAdditionalItemDefinitions());\n        }\n\n        // Merge in defaults\n        extraItems = extraItems.concat(\n            [\n                {\n                    'detectType': 'dom',\n                    'detectSelector': 'body.wp-admin #wp-admin-bar-view-site a',\n                    'itemTitleFunction': () => 'View/visit site',\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-dashboard a',\n                    'itemTitleFunction': (element) => element.textContent,\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wpadminbar',\n                    'itemTitleFunction': () => 'Logout',\n                    'itemUrlFunction': () => document.getElementById('wp-admin-bar-logout')?.querySelector('a')?.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-edit a',\n                    'itemTitleFunction': (item) => item.textContent,\n                    'itemUrlFunction': (item) => item.href,\n                    'noCache': true,\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-view a',\n                    'itemTitleFunction': (item) => item.textContent,\n                    'itemUrlFunction': (item) => item.href,\n                    'noCache': true,\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-new-content .ab-submenu a',\n                    'itemTitleFunction': (item) => 'New ' + item.textContent,\n                    'itemUrlFunction': (item) => item.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-customize a',\n                    'itemTitleFunction': (item) => item.textContent,\n                    'itemUrlFunction': (item) => item.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelectorNone': '#wpadminbar, #loginform',\n                    'itemTitleFunction': () => \"Log in\",\n                    'itemUrlFunction': () => {\n                        if (globalThis.taWp.home) {\n                            return globalThis.taWp.siteUrl;\n                        }\n                        // Try getting wp-admin\n                        return 'javascript:alert(\\'Sorry, could not detect login URL.\\')';\n                    }\n                },\n                // This is on the login screen\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#backtoblog a',\n                    'itemTitleFunction': () => \"View/visit site\",\n                    'itemUrlFunction': (element) => element.href\n                },\n                // Multisite items\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-network-admin > a',\n                    'itemTitleFunction': () => \"Network Admin\",\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-network-admin .ab-submenu a',\n                    'itemTitleFunction': (element) => 'Network Admin: ' + element.textContent,\n                    'itemUrlFunction': (element) => element.href\n                },\n            ]\n        );\n\n        extraItems.forEach(item => {\n            let detected = false;\n            let elements = null;\n            if (item.detectType === 'url') {\n                detected = Boolean(window.location.href.includes(item.detectPattern));\n            } else if (item.detectType === 'dom') {\n                if (item.detectSelector) {\n                    elements = document.querySelectorAll(item.detectSelector);\n                    detected = Boolean(elements);\n                } else if (item.detectSelectorNone) {\n                    elements = document.querySelectorAll(item.detectSelectorNone);\n                    detected = elements.length === 0;\n                    // Need to pass SOMETHING to the loop below\n                    elements = document.querySelectorAll('body');\n                }\n            }\n            if (!detected) {\n                return;\n            }\n\n            elements.forEach(element => {\n                const newItem = new TurboAdminMenuItem(item.itemTitleFunction(element), item.itemUrlFunction(element), '', item?.noCache);\n                // Might already have one so check.\n                if (this.menu.some(menuItem => {\n                    // This must be newItem.sameAs, not menuItem.sameAs because the menuItem\n                    // may have been loaded from saved menu and may not actually be an instance\n                    // of a TurboAdminMenuItem.\n                    return newItem.sameAs(menuItem)\n                } )) {\n                    return;\n                }\n                // We don't already have one. So add it.\n                this.menu.push(newItem);\n            });\n        })\n    }\n\n    /**\n     * Builds the palette HTML and adds it to the DOM.\n     */\n    addPalette() {\n        const container = document.createElement('div');\n        container.id = 'ta-command-palette-container';\n        // Palette\n        const palette = document.createElement('div');\n        palette.id = 'ta-command-palette';\n        // Palette notice\n        const paletteNotice = document.createElement('div');\n        paletteNotice.id = 'ta-command-palette-notice';\n        // Tab notice\n        const tabNotice = document.createElement('div');\n        tabNotice.id = 'ta-command-palette-tab-notice';\n        // Tab notice text\n        const tabNoticeText = document.createElement('span');\n        tabNoticeText.id = 'ta-command-palette-tab-notice-text';\n        // Tab notice \"button\"\n        const tabNoticeButton = document.createElement('span');\n        tabNoticeButton.id = 'ta-command-palette-tab-notice-button';\n        tabNoticeButton.innerText = 'Tab';\n        // Input field\n        const input = document.createElement('input');\n        input.id = \"ta-command-palette-input\";\n        input.name = \"ta-command-palette-input\";\n        input.type = \"text\";\n        // Set this to stop stuff trying to fill it.\n        input.setAttribute('autocomplete', 'off');\n        // Search mode tag\n        const searchModeTag = document.createElement('div');\n        searchModeTag.id = 'ta-command-palette-search-mode-tag';\n        // List container (needed to contain the main list and the submenu list)\n        const listContainer = document.createElement('div');\n        listContainer.id = \"ta-command-palette-items-container\";\n        // List\n        const list = document.createElement('ul');\n        list.id = \"ta-command-palette-items\";\n        // Sub-menu list\n        const submenuContainer = document.createElement('div');\n        submenuContainer.id = \"ta-command-palette-submenu-container\";\n        // Join it all up\n        container.appendChild(palette);\n        palette.appendChild(searchModeTag);\n        palette.appendChild(paletteNotice);\n        tabNotice.appendChild(tabNoticeText);\n        tabNotice.appendChild(tabNoticeButton);\n        palette.appendChild(tabNotice);\n        palette.appendChild(input);\n        listContainer.appendChild(list);\n        listContainer.appendChild(submenuContainer);\n        palette.appendChild(listContainer);\n\n        if (document.getElementById('wpadminbar') && this.options['admin-bar-search'] === true) {\n            const paletteLi = document.createElement('li');\n            paletteLi.appendChild(container);\n            const adminBar = document.getElementById('wp-admin-bar-top-secondary');\n            adminBar.appendChild(paletteLi);\n\n            // Add focus handler\n            input.addEventListener('focus', e => this.turboAdminPalette.showPalette());\n\n            // Add placeholder\n            const placeholder = document.createElement('div');\n            placeholder.id = 'ta-shortcut-key-placeholder';\n            placeholder.innerText = this.buildShortcutKeysString();\n            placeholder.addEventListener('click', e => input.focus());\n\n            palette.insertBefore( placeholder, listContainer );\n        } else {\n            // Container\n            document.querySelector(this.options.appendToElement ?? 'body').appendChild(container);\n        }\n    }\n\n    /**\n     * Register a plugin with Turbo Admin\n     *\n     * @param {TurboAdminPlugin} plugin\n     */\n    registerPlugin(plugin) {\n        console.log('Registering plugin ' + plugin.name);\n        this.plugins[plugin.name] = plugin;\n    }\n\n    /**\n     * Register a palette search mode and its associated plugin\n     *\n     * this is usually bound to the searchMode, so\n     *\n     * @param {SearchMode} searchMode\n     */\n    registerSearchMode(searchMode) {\n        console.log('Registering search mode with keyword ' + searchMode.keyword);\n        // Don't use `this` as we are bound!\n        globalThis.turboAdmin.searchModes[searchMode.keyword] = searchMode;\n    }\n\n    /**\n     * Returns a string representation of the palette's keyboard shortcut\n     *\n     * @returns { String }\n     */\n    buildShortcutKeysString () {\n        let keysString = '';\n        let shortcut = this.options.shortcutKeys[0];\n\n        if ( shortcut.meta ) {\n            keysString += 'Cmd-';\n        }\n        if ( shortcut.ctrl ) {\n            keysString += 'Ctrl-';\n        }\n        if ( shortcut.alt ) {\n            keysString += 'Alt-';\n        }\n        if ( shortcut.shift ) {\n            keysString += 'Shift-';\n        }\n        keysString += shortcut.key;\n        return keysString;\n    }\n\n}\n", "export default class Wp {\n\n    constructor() {\n\n        // Set home and siteUrl\n        this.siteUrl = '';\n        this.home = '';\n        this.loginUrl = '';\n        this.apiLinkUrl = '';\n    }\n\n    async completeInit() {\n        // Fetch previously loaded site URL\n        this.previousUrl = window.localStorage.getItem('ta-palette-data-site');\n\n        // Fetch previously-stored siteUrl and home\n        this.siteUrl = window.localStorage.getItem('ta-palette-data-siteurl');\n        this.home = window.localStorage.getItem('ta-palette-data-home');\n\n        /**\n         * Are we in the back-end?\n         */\n        this.isBackend = this.getIsBackend();\n\n        /**\n         * Figure out all the WP URLs\n         */\n        await this.getUrls();\n\n        /**\n         * Tells you if the best-guess site URL of the current page is different\n         * to that of the previously saved site URL.\n         */\n        this.siteChanged = this.home !== this.previousUrl;\n\n        // Save current site URL for next time\n        window.localStorage.setItem('ta-palette-data-site', this.home);\n    }\n\n    getIsBackend() {\n        return document.body.classList.contains('wp-admin');\n    }\n\n    /**\n     * Return the URL with a trailing slash if it didn't already have one.\n     *\n     * @param {String} url The URL to check\n     * @return {String}    The resulting URL\n     */\n    ensureTrailingSlash( url ) {\n        if (url.endsWith('/')) {\n            return url;\n        } else {\n            return url + '/';\n        }\n    }\n\n    /**\n     * Tests if a URL works and, if redirected, that the final URL contains a given\n     * string. Returns the final, redirected-to URL if the test passed, or false\n     * otherwise.\n     *\n     * @param {String} url                    The URL to test.\n     * @param {String} responseUrlMustContain The string to test against the final URL\n     * @returns {Promise<String|Boolean>}   The final URL or false.\n     */\n    async testUrl(url, responseUrlMustContain='') {\n\n        /** @type {RequestInit} */\n        const init = {\n            method: 'HEAD',\n            mode: 'cors',\n            cache: 'no-cache',\n            credentials: 'same-origin'\n        }\n\n        const response = await fetch(url, init);\n\n        if (response.redirected && !response.url.includes(responseUrlMustContain)) {\n            return false;\n        }\n\n        if ( ! response.ok ) {\n            return false;\n        }\n\n        return response.url;\n    }\n\n    async findWhichUrlWorks(urls, responseUrlMustContain='') {\n        let workingUrl = false;\n        let result;\n        // This has to be a for loop rather than reduce or forEach as separate\n        // async callbacks would be launched asynchronously.\n        for (let i=0; i<urls.length; i++) {\n            if (workingUrl) continue;\n            result = await this.testUrl(urls[i], responseUrlMustContain);\n            if (result !== false) {\n                workingUrl = result;\n            }\n        }\n        return workingUrl;\n    }\n\n    /**\n     *\n     * @param {String} homeUrl\n     */\n    async guessSiteUrlFromHome( homeUrl ) {\n        const homeWithSlash = this.ensureTrailingSlash(homeUrl);\n\n        // NOTE: Backed out of this until I can make it work async.\n        // Might not even be a good idea anyway.\n\n        // const possibleUrls = [\n        //     homeWithSlash + 'wp-admin/',\n        //     homeWithSlash + 'wp/wp-admin'\n        // ];\n        // return this.findWhichUrlWorks(possibleUrls, 'wp-admin');\n        return homeWithSlash + 'wp-admin/';\n    }\n\n    /**\n     *\n     * @param {String} homeUrl\n     */\n    async guessHome() {\n        const currentUrl = new URL(window.location);\n        const origin = this.ensureTrailingSlash(currentUrl.origin);\n\n        // NOTE: Backed out of this until I can make it work async.\n        // Might not even be a good idea anyway.\n\n        // const possibleUrls = [\n        //     origin\n        // ];\n        // return this.findWhichUrlWorks(possibleUrls, 'wp-admin');\n        return origin;\n    }\n\n    /**\n     *\n     * @param {String} siteUrl\n     * @returns {String}\n     */\n    guessHomeFromSiteUrl(siteUrl) {\n        // Not much we can do here.\n        return siteUrl.replace(/wp-admin\\/?/, '');\n    }\n\n    async getUrls() {\n        // See if we can actually find the URL for the API\n        /** @type {HTMLLinkElement|null} */\n        const apiLink = document.querySelector('link[rel=\"https://api.w.org/\"]');\n\n        if (apiLink) {\n            this.apiLinkUrl = apiLink.href;\n        }\n        // Figure out the siteurl and home - this is different on the front and back end\n        if (this.isBackend) {\n            // This is easy in the back end/Dashboard!\n            this.siteUrl = window.location.href.match(/(^.*wp-admin)/)[1];\n            this.home = document.getElementById('wp-admin-bar-site-name').querySelector('a').href;\n\n            // Always set the siteUrl and home as this is definitive\n            window.localStorage.setItem('ta-palette-data-siteurl', this.siteUrl);\n            window.localStorage.setItem('ta-palette-data-home', this.home);\n        } else if (! this.siteUrl || ! this.home) {\n\n            // If we're not in the backend then (in the extension at least) we\n            // could be on the front-end and not logged in, so check for an\n            // admin bar and grab from that if there is one.\n            if (document.getElementById('wpadminbar')) {\n                this.siteUrl = document.getElementById('wp-admin-bar-dashboard').querySelector('a').href;\n                // Try for the API link\n                if (this.apiLinkUrl) {\n                    if (this.apiLinkUrl.includes('/wp-json')) {\n                        this.home = this.apiLinkUrl.replace('wp-json/', '');\n                    }\n                    if (this.apiLinkUrl.includes('index.php?rest_route')) {\n                        this.home = this.apiLinkUrl.replace(/index.php\\?rest_route.*/, '');\n                    }\n                } else {\n                    // We know what the siteUrl is, so guess the home from the siteUrl\n                    this.home = this.guessHomeFromSiteUrl(this.siteUrl);\n                }\n\n            } else {\n                // Try for the API link\n                // TODO: This needs to be async so it doesn't hold things up.\n                if (this.apiLinkUrl) {\n                    if (this.apiLinkUrl.includes('/wp-json')) {\n                        this.home = this.apiLinkUrl.replace('wp-json/', '');\n                    }\n                    if (this.apiLinkUrl.includes('index.php?rest_route')) {\n                        this.home = this.apiLinkUrl.replace(/index.php\\?rest_route.*/, '');\n                    }\n                    // We (probably) know what the home link is now, so guess the wp-admin\n                    if (this.home) {\n                        this.siteUrl = await this.guessSiteUrlFromHome( this.home );\n                    } else {\n                        this.siteUrl = this.guessSiteUrl();\n                    }\n                } else {\n                    // We got nothing.\n                    this.home    = await this.guessHome();\n                    if (this.home) {\n                        this.siteUrl = await this.guessSiteUrlFromHome(this.home);\n                    }\n                }\n            }\n        }\n\n        // Always trim the / for comparisons\n        if (this.siteUrl) {\n            this.siteUrl = this.siteUrl.replace(/(.+)\\/$/, '$1');\n        }\n        if (this.home) {\n            this.home = this.home.replace(/(.+)\\/$/, '$1');\n        }\n\n        // console.log('siteUrl: ', this.siteUrl);\n        // console.log('home: ', this.home);\n    }\n\n}\n", "import Storage from '../class-storage.js';\n// import ContentApi from './class-content-api.js';\n\nexport default class WoocommerceApi {\n\n    constructor() {\n        // This is used to \"cache\" duplicate requests.\n        // It's an object because it will have search strings as keys\n        this.cache = {};\n    }\n\n    async getOrders(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['orders-' + searchString]) {\n            return this.cache['orders-' + searchString];\n        }\n\n        // Fetch results\n        const response = await this.wooGet(\n            \"orders\",\n            {\n                search: searchString,\n                per_page: 100,\n            }\n        );\n\n        if (response === false) {\n            return false;\n        }\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['orders-' + searchString] = result;\n\n        return result;\n    }\n\n    async getOrder(orderId) {\n        // Check the cache\n        if (undefined !== this.cache['order-' + orderId]) {\n            return this.cache['order-' + orderId];\n        }\n\n        // Fetch results\n        const response = await this.wooGet(\n            `orders/${orderId}`\n        );\n\n        if (response === false) {\n            return false;\n        }\n\n        // Decode JSON\n        const result = await response.json();\n\n        let resultAsArray = [ result ];\n\n        // Store in the cache\n        this.cache['order-' + orderId] = resultAsArray;\n\n        return resultAsArray;\n    }\n\n    async getCustomers(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['customers-' + searchString]) {\n            return this.cache['customers-' + searchString];\n        }\n\n        // Fetch results\n        const response = await this.wooGet(\n            \"customers\",\n            {\n                search: searchString,\n                per_page: 100,\n                role: 'all',\n            }\n        );\n\n        if (response === false) {\n            return false;\n        }\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['customers-' + searchString] = result;\n\n        return result;\n    }\n\n    // TODO: Add docblock and types\n    async wooGet(path, data = {}) {\n        const wooApiBase = globalThis.contentApi.apiRoot + 'wc/v3/';\n\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n            credentials: 'include'\n        }\n\n        // Add the nonce if there is one\n        if (globalThis.contentApi.apiNonce) {\n            data._wpnonce = globalThis.contentApi.apiNonce;\n        }\n\n        const params = globalThis.contentApi.makeParamString(data);\n\n        const response = await fetch(`${wooApiBase}${path}/?${params}`, init);\n\n        if ( response.status === 404 ) {\n            return false;\n        }\n        if ( (response.status < 200 || response.status >= 300) ) {\n            globalThis.turboAdmin.turboAdminPalette.showPaletteNotice('WooCommerce API Error. Try visiting the dashboard to refresh things.');\n        }\n\n        return response;\n    }\n\n}\n", "import Storage from '../class-storage.js';\n// import ContentApi from './class-content-api.js';\n\nexport default class GravityFormsApi {\n\n    constructor() {\n        // This is used to \"cache\" duplicate requests.\n        // It's an object because it will have search strings as keys\n        this.cache = {};\n    }\n\n    async getForms(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['gf-forms-' + searchString]) {\n            return this.cache['gf-forms-' + searchString];\n        }\n\n        // Fetch results\n        const response = await this.gfGet(\n            \"forms\",\n            {}\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // TODO: Trap for errors\n\n        // Filter by search string - the API doesn't do this for us\n        const searchStringLowerCase = searchString.toLowerCase();\n        const formIds = Object.keys(result);\n        for (let k = 0; k < formIds.length; k++) {\n            const thisId = formIds[k];\n            if (! result[thisId].title.toLowerCase().includes(searchStringLowerCase)) {\n                delete result[thisId];\n            }\n        }\n\n        // Store in the cache\n        this.cache['gf-forms-' + searchString] = result;\n\n        return result;\n    }\n\n    async gfGet(path, data = {}) {\n        const gfApiBase = globalThis.contentApi.apiRoot + 'gf/v2/';\n\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n            credentials: 'include'\n        }\n\n        // Add the nonce if there is one\n        if (globalThis.contentApi.apiNonce) {\n            data._wpnonce = globalThis.contentApi.apiNonce;\n        }\n\n        const params = globalThis.contentApi.makeParamString(data);\n\n        const response = await fetch(`${gfApiBase}${path}/?${params}`);\n\n        if (response.status < 200 || response.status >= 300) {\n            globalThis.turboAdmin.turboAdminPalette.showPaletteNotice('Gravity Forms API Error. Try visiting the dashboard to refresh things.');\n        }\n\n        return response;\n    }\n\n}\n", "import TurboAdmin from './class-turbo-admin.js';\nimport ContentApi from './apis/class-content-api.js';\nimport Wp from './class-wp.js';\nimport TurboAdminWpNotices from './class-turbo-admin-wp-notices.js';\nimport WoocommerceApi from './apis/class-woocommerce-api.js';\nimport GravityFormsApi from './apis/class-gravity-forms-api.js';\n\nconst taStorageKey = 'turbo-admin-settings';\n\n// Use this to clear storage\n// browser.storage.local.remove(taStorageKey).then();\n\n// Note that in the extension, the globalThis is not the browser's global scope,\n// it is sandboxed. So we can't check across the plugin/extension boundary here.\nasync function taInit(settings) {\n\n    if (typeof(globalThis.turboAdmin) !== 'undefined') {\n        // Already initialised for some reason\n        return;\n    }\n    globalThis.turboAdmin = null;\n\n    // Handle empty settings\n    if (typeof(settings[taStorageKey]) === 'undefined') {\n        console.log('Weird. Turbo Admin could not find any settings');\n        return;\n    }\n\n    globalThis.turboAdminOptions = settings[taStorageKey];\n\n    console.log('Preparing Turbo Admin');\n\n    // Get Wp stuff ready\n    globalThis.taWp = new Wp();\n\n    // Parts of this init are async.\n    await globalThis.taWp.completeInit();\n\n    console.log('Turbo Admin: WP is initialised');\n\n    // Get/set api settings\n    globalThis.contentApi = new ContentApi();\n    await globalThis.contentApi.discoverApiRoot();\n    await globalThis.contentApi.discoverPostTypes();\n    globalThis.woocommerceApi = new WoocommerceApi();\n    globalThis.gravityFormsApi = new GravityFormsApi();\n\n    console.log('Turbo Admin: Content API is initialised');\n\n    globalThis.turboAdmin = new TurboAdmin(globalThis.turboAdminOptions);\n    await globalThis.turboAdmin.init();\n\n\n\n    // This needs all the APIs to be ready\n    await globalThis.turboAdmin.activatePlugins();\n\n    if (settings[taStorageKey]['hide-notices']) {\n        globalThis.turboAdminWpNotices = new TurboAdminWpNotices(settings[taStorageKey].rememberedNoticeIds);\n    }\n}\n\n/**\n * This is plugin-specific. It should not be present in the extension code.\n */\ndocument.addEventListener('DOMContentLoaded', async e => {\n\tglobalThis.turboAdminOptions = {};\n\tglobalThis.turboAdminOptions[taStorageKey] = {\n\t\t// wpTurboAdmin is set using wp_localize_script\n\t\tshortcutKeys: globalThis.wpTurboAdmin.keys,\n        // These don't apply to the plugin version\n        'block-editor-fullscreen-disable': false,\n        'block-editor-welcome-screen-kill': false,\n        // I don't think we'll do this in the plugin as the code would be SO different.\n        'live-dev-notice': false,\n        'list-table-keyboard-shortcuts': globalThis.wpTurboAdmin['listTableShortcuts'] === '1',\n        'hide-notices': globalThis.wpTurboAdmin['hideNotices'] === '1',\n        'rememberedNoticeIds': JSON.parse(window.localStorage.getItem('rememberedNoticeIds')) ?? new Array(),\n        'barkeeper': globalThis.wpTurboAdmin['barkeeper'] === '1',\n        'admin-bar-search': globalThis.wpTurboAdmin['adminBarSearch'] === '1',\n\t}\n\tawait taInit(globalThis.turboAdminOptions);\n});\n"],
     5  "mappings": "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",
    66  "names": []
    77}
  • turbo-admin/tags/1.12.0/readme.txt

    r2748309 r2835882  
    44Tags: menu, commands, shortcuts
    55Requires at least: 4.9
    6 Tested up to: 6.0
     6Tested up to: 6.1
    77Requires PHP: 7.2
    8 Stable tag: 1.9.0
     8Stable tag: 1.12.0
    99License: GPLv2 or later
    1010License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    3232* (Experimental/Beta): List table keyboard shortcuts - use vim-like keys to navigate lsit tables.
    3333
    34 If you love this plugin, you can get Turbo Admin on ALL your sites without needing to install the plugin, with the browser extension version!
    35 
    36 PLUS the browser extension has features not present in the plugin because, well, they only make sense in the extension!
    37 
     34If you love this plugin, you can get Turbo Admin on ALL your sites without needing to install the plugin, PLUS additional premium features, with [the browser extension version](https://turbo-admin.com/)!
     35
     36PLUS the browser extension has features not present in the plugin. Some features only make sense in the extension, others are considered "premium" and are only available in the browser extension.
     37
     38* WooCommerce search (premium - extension only)
     39* Gravity Forms Search (premium - extension only)
    3840* Full screen block editor killer
    3941* Block editor welcome guide remover
    4042* Live/dev site labels
    4143
    42 Remember, the browser extension it works everywhere that it can detect WordPress without needing a plugin. And it carries your preferences with you! It's WordPress, your way!
     44Remember, the browser extension it works everywhere that it can detect WordPress, without needing a plugin. And it carries your preferences with you! It's WordPress, your way!
    4345
    4446[Check out the Browser Extension and try it for free](https://turbo-admin.com/)
     
    7476If you hold Ctrl/Cmd when selecting an item it will open in a new tab/window (you may need to allow your browser to open popups).
    7577
    76 As well as commands, the plugin will also search content that is made available through the REST API (as long as the REST API can be discovered).
     78## Search modes
     79
     80As well as commands, the plugin can also search content that is made available through the REST API (as long as the REST API can be discovered).
     81
     82This is done using "search modes".
     83
     84For example, if you type "post" and then press the tab key (or type a colon) you will switch to the "post" search mode. In this mode you are searching for posts.
     85
     86Turbo Admin automatically creates search modes for any public post types on your site. It also creates the following search modes:
     87
     88* user
     89* plugin
     90* site (for WordPress Multisite sites)
     91
     92There is full documentation of search modes on [the Turbo Admin website](https://turbo-admin.com/searching.html)
    7793
    7894## Admin bar search mode
     
    169185== Changelog ==
    170186
     187= 1.12.0 =
     188* [FEATURE] Search modes
     189* [FEATURE] User search
     190* [FEATURE] Plugin search
     191* [ENHANCEMENT] Command palette core re-written to be faster, more reliable and more extensible.
     192
    171193= 1.9.0 =
    172194* [FEATURE] Admin bar search mode
  • turbo-admin/tags/1.12.0/src/class-turbo-admin-palette.js

    r2703739 r2835882  
    1818
    1919import Fuse from './fuse-6.4.6.js';
    20 import TurboAdminMenuItem from './class-turbo-admin-menu-item';
    21 import ContentApi from './class-content-api.js';
     20import TurboAdminMenuItem from './types/class-turbo-admin-menu-item';
     21import ContentApi from './apis/class-content-api.js';
     22import SearchMode from './types/class-search-mode.js';
     23import ContentItem from './types/class-content-item.js';
    2224
    2325export default class TurboAdminPalette {
     
    3537        /** @type {HTMLInputElement} */
    3638        this.paletteInputElement = /** @type {HTMLInputElement} */ (document.getElementById('ta-command-palette-input'));
     39        /** @type {HTMLDivElement} */
     40        this.paletteItemsContainerElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-items-container'));
    3741        /** @type {HTMLUListElement} */
    3842        this.paletteItemsElement = /** @type {HTMLUListElement} */ (document.getElementById('ta-command-palette-items'));
     43        /** @type {HTMLDivElement} */
     44        this.paletteSubmenuContainerElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-submenu-container'));
     45        /** @type {HTMLDivElement} */
     46        this.paletteSearchModeTag = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-search-mode-tag'));
     47        /** @type {HTMLDivElement} */
     48        this.paletteSearchModeTabNotice = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-tab-notice'));
     49        /** @type {HTMLSpanElement} */
     50        this.paletteSearchModeTabNoticeText = /** @type {HTMLSpanElement} */ (document.getElementById('ta-command-palette-tab-notice-text'));
     51        /** @type {HTMLDivElement} */
     52        this.paletteNoticeElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-notice'));
     53
     54
     55        // Add a class if the menu needs refreshing with a visit to the Dashboard
     56        if (globalThis.turboAdmin.menuNeedsRefresh) {
     57            this.showPaletteNotice('Menu needs refreshing. Visit the Dashboard to refresh.');
     58        }
     59
     60        // We need this when injecting items. We use it to help generate edit URLs. Not the best way but
     61        // works for now.
     62        /** @type {HTMLUListElement} */
     63        this.profileLinkElem = document.getElementById('wp-admin-bar-edit-profile');
     64        /** @type {null|String} */
     65        this.profileLink = null;
     66        if (this.profileLinkElem) {
     67            this.profileLink = this.profileLinkElem.querySelector('a').href;
     68        }
    3969
    4070        // Get palette data
    4171        this.paletteData = paletteData;
    4272
    43         // Get post type data from API
    44         this.postTypes = [];
    45         this.fetchPostTypes();
     73        // Backup of the palette data for use when we enter a different search mode
     74        this.paletteDataBackup = null;
     75        this.paletteItemsBackup = null;
     76        this.paletteItemIndexBackup = null;
     77
     78        // Current search modes/keyword
     79        this.searchMode = null;
    4680
    4781        // paletteItems is the list of 'li' elements used to build the palette
     
    105139    }
    106140
    107     fetchPostTypes() {
    108         if (! globalThis.contentApi.active) {
    109             this.postTypes = [];
    110             return;
    111         }
    112 
    113         globalThis.contentApi.get('types').then(
    114             response => {
    115                 response.json().then(
    116                     types => {
    117                         this.postTypes = types;
    118                     }
    119                 );
    120             }
    121         );
    122     }
    123 
    124     buildPaletteItems() {
     141    inSearchMode() {
     142        return this.searchMode !== null;
     143    }
     144
     145    /**
     146     * This converts this.paletteData into a list of paletteListItems in this.paletteItems
     147     *
     148     * It also builds the itemIndex
     149     */
     150    buildPaletteItems() {
    125151        this.paletteItems = [];
    126152        this.itemIndex = {};
     
    155181    }
    156182
    157     injectContentItems(contentItems) {
     183    /**
     184     * Clears and sets the content items
     185     *
     186     * @param {ContentItem[]} contentItems
     187     */
     188    setContentItems(contentItems) {
     189        this.paletteItems = [];
     190        this.itemIndex = [];
     191        this.injectContentItems(contentItems, false);
     192    }
     193
     194    /**
     195     * Content items have:
     196     *  title
     197     *  subtype
     198     *  url
     199     *  (we should also make the sub-menu definable, but that's not done yet)
     200     *
     201     * @param {ContentItem[]} contentItems
     202     */
     203    injectContentItems(contentItems, andRunSearch = true) {
    158204        console.log('Injecting items');
    159205
    160         // We'll need this in the loop below.
    161         const profileLinkElem = document.getElementById('wp-admin-bar-edit-profile');
    162         let profileLink = null;
    163         if (profileLinkElem) {
    164             profileLink = profileLinkElem.querySelector('a').href;
    165         }
    166 
    167         // TODO: Can we not do this on every content item inject?
    168         // Check for presence of Oxygen Page builder
    169         /** @type {HTMLElement|string|Number} */
    170         let oxygenLinkElem = document.getElementById('toplevel_page_ct_dashboard_page');
    171         // Also check for a menu bar item
    172         if (! oxygenLinkElem) {
    173             oxygenLinkElem = document.getElementById('wp-admin-bar-oxygen_admin_bar_menu');
    174         }
    175         // Check to see if Oxygen link is cached
    176         if (! oxygenLinkElem) {
    177             oxygenLinkElem = Number(window.localStorage.getItem('ta-has-oxygen-builder'));
    178         }
    179         // Save Oxygen builder status
    180         window.localStorage.setItem('ta-has-oxygen-builder', Boolean(oxygenLinkElem) ? '1' : '0' );
    181 
    182206        if (contentItems.length > 0) {
    183             contentItems.forEach(item => {
    184                 const itemTitle = item.title;
    185                 // const itemTitle = item.title.rendered;
    186                 const itemType = item.subtype;
    187                 const itemUrl = item.url;
    188 
    189                 // console.log('Adding item: ' + itemTitle);
    190 
    191                 // // Check if item already exists
    192                 if (this.contentItemExists(itemUrl)) {
    193                     console.log('Not adding duplicate');
    194                     return;
     207            contentItems.forEach(this.injectItem.bind(this));
     208        }
     209
     210        if (andRunSearch) {
     211            // Reset the search to work on the new items
     212            this.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);
     213            this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map(i => i.item);
     214        }
     215
     216        this.updatePaletteItems();
     217    }
     218
     219    /**
     220     * Injects a single content item into the palette
     221     *
     222     * @param {ContentItem} item
     223     */
     224    injectItem(item) {
     225        const itemTitle = item.title;
     226        // const itemTitle = item.title.rendered;
     227        const itemType = item.subtype;
     228        const itemUrl = item.url;
     229
     230        // console.log('Adding item: ' + itemTitle);
     231
     232        // // Check if item already exists
     233        if (this.contentItemExists(itemUrl)) {
     234            console.log('Not adding duplicate');
     235            return;
     236        }
     237
     238        let title = itemTitle;
     239
     240        if (itemType) {
     241            const itemTypeName = globalThis.contentApi.postTypes[itemType] ? globalThis.contentApi.postTypes[itemType].name : itemType;
     242            title += ` (${itemTypeName})`;
     243        }
     244
     245        const li = document.createElement('li');
     246        const a = document.createElement('a');
     247        let subMenu = null;
     248
     249        // Loop over submenu items OR add link.
     250        if (item.submenuItems.length > 0) {
     251
     252            // Prepare the outer sub-menu elements
     253            subMenu = document.createElement('div');
     254            const subMenuTitle = document.createElement('div');
     255            const subMenuItems = document.createElement('ul');
     256            subMenu.classList.add('ta-submenu');
     257            subMenuTitle.classList.add('ta-submenu-title');
     258
     259            subMenuTitle.textContent = this.htmlDecode(itemTitle);
     260            subMenuItems.classList.add('ta-submenu-items');
     261            subMenu.appendChild(subMenuTitle);
     262
     263            for (let i = 0; i < item.submenuItems.length; i++) {
     264                const subMenuItem = item.submenuItems[i]
     265                // TODO: Abstract this so sub-menus can be defined by plugins?
     266                const subMenuListItem = document.createElement('li');
     267                const subMenuLink = document.createElement('a');
     268                subMenuLink.innerText = subMenuItem.title;
     269                subMenuLink.href = subMenuItem.url;
     270                for (let a = 0; a < subMenuItem.attributes.length; a++) {
     271                    subMenuLink.setAttribute(
     272                        subMenuItem.attributes[a].name,
     273                        subMenuItem.attributes[a].value
     274                    )
    195275                }
    196 
    197                 const itemTypeName = this.postTypes[itemType] ? this.postTypes[itemType].name : itemType;
    198                 const title = `${itemTitle} (${itemTypeName})`;
    199 
    200                 const li = document.createElement('li');
    201                 const a = document.createElement('a');
    202                 const subMenu = document.createElement('div');
    203                 const subMenuTitle = document.createElement('div');
    204                 const subMenuItems = document.createElement('ul');
    205                 subMenu.classList.add('ta-submenu');
    206                 subMenuTitle.classList.add('ta-submenu-title');
    207 
    208                 subMenuTitle.textContent = this.htmlDecode(itemTitle);
    209                 subMenuItems.classList.add('ta-submenu-items');
    210                 subMenu.appendChild(subMenuTitle);
    211                 subMenu.appendChild(subMenuItems);
    212 
    213                 const subMenuItem1 = document.createElement('li');
    214                 const subMenuLink1 = document.createElement('a');
    215                 subMenuLink1.innerText = "View";
    216                 subMenuLink1.href = itemUrl;
    217                 subMenuItem1.appendChild(subMenuLink1);
    218                 subMenuItems.appendChild(subMenuItem1);
    219 
    220                 if (profileLink) {
    221                     // Need to get edit URL. This seems like the best way for now.
    222                     const editLink = profileLink.replace('profile.php', `post.php?post=${item.id}&action=edit`);
    223 
    224                     const subMenuItem2 = document.createElement('li');
    225                     const subMenuLink2 = document.createElement('a');
    226                     subMenuLink2.innerText = "Edit";
    227                     subMenuLink2.href = editLink;
    228                     subMenuItem2.appendChild(subMenuLink2);
    229                     subMenuItems.appendChild(subMenuItem2);
    230                 }
    231 
    232                 if (oxygenLinkElem) {
    233                     // Oxygen Edit Links are like: https://example.com.com/?page_id=26&ct_builder=true&ct_inner=true
    234                     const oxygenLink = globalThis.taWp.home + `?page_id=${item.id}&ct_builder=true&ct_inner=true`;
    235 
    236                     const subMenuItem3 = document.createElement('li');
    237                     const subMenuLink3 = document.createElement('a');
    238                     subMenuLink3.innerText = "Edit with Oxygen";
    239                     subMenuLink3.href = oxygenLink;
    240                     subMenuItem3.appendChild(subMenuLink3);
    241                     subMenuItems.appendChild(subMenuItem3);
    242                 }
    243 
    244                 const subMenuItem3 = document.createElement('li');
    245                 const subMenuLink3 = document.createElement('a');
    246                 subMenuLink3.innerText = "Copy link";
    247                 // Because this is an href we're setting it gets URI encoded!
    248                 subMenuLink3.href = itemUrl;
    249                 subMenuLink3.setAttribute('data-action', 'clipboard');
    250                 subMenuItem3.appendChild(subMenuLink3);
    251                 subMenuItems.appendChild(subMenuItem3);
    252 
    253 
    254                 li.classList.add('ta-has-child-menu');
    255 
    256                 li.appendChild(a);
    257                 li.appendChild(subMenu);
    258 
    259                 a.href = itemUrl;
    260                 a.innerHTML = title;
    261                 this.addPaletteListItem(li);
    262             })
    263         }
    264 
    265         // Reset the search to work on the new items
    266         this.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);
    267         this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map(i => i.item);
    268 
    269         this.updatePaletteItems();
     276                subMenuListItem.appendChild(subMenuLink);
     277                subMenuItems.appendChild(subMenuListItem);
     278            }
     279
     280            // Add the sub-menu items UL to the sub-menu element.
     281            subMenu.appendChild(subMenuItems);
     282
     283            li.classList.add('ta-has-child-menu');
     284        }
     285
     286        a.href = itemUrl;
     287        a.innerHTML = title;
     288
     289        li.appendChild(a);
     290        if (subMenu !== null) {
     291            li.appendChild(subMenu);
     292        }
     293
     294        this.addPaletteListItem(li);
    270295    }
    271296
     
    285310                this.showPalette();
    286311            }
     312            return;
    287313        }
    288314
     
    290316            if (this.isSubMenuOpen()){
    291317                this.closeSubMenu();
     318            } else if (this.inSearchMode()) {
     319                this.leaveSearchMode();
    292320            } else {
    293321                this.hidePalette();
    294322            }
     323            return;
    295324        }
    296325
     
    320349    }
    321350
     351    /*
     352     * Adds the tab hint for a keyword once it has been typed.
     353     */
     354    maybeHighlightInputKeyword(newKey) {
     355        // Do nothing if we are in a search-mode
     356        if (this.inSearchMode()) {
     357            return;
     358        }
     359
     360        // This is fired on "keyDown", so the value isn't update with the new key yet.
     361        // But don't do this for special keys, and catch backspace too.
     362        let newInputValue = this.paletteInputElement.value;
     363        if (newKey.length === 1) {
     364            newInputValue += newKey;
     365        }
     366        if (newKey === 'Backspace') {
     367            newInputValue = newInputValue.slice(0, -1);
     368        }
     369        // console.log(`Checking palette input value ${newInputValue} for keyword`);
     370        if (this.isKeyword(newInputValue)) {
     371            this.paletteSearchModeTabNoticeText.innerText = `Search for ${newInputValue}`;
     372            this.paletteSearchModeTabNotice.classList.add('active');
     373        } else {
     374            this.unhighlightInputKeyword();
     375        }
     376    }
     377
     378    unhighlightInputKeyword() {
     379        this.paletteSearchModeTabNotice.classList.remove('active');
     380    }
     381
    322382    async debouncedPaletteSearchAndUpdate() {
    323         // If search string is not long enough for content search, then
    324         // run without debounce.
    325         if (
    326             ( this.paletteInputElement.value !== '' && this.paletteInputElement.value.length <= 2)
    327             || this.postTypes === [] ) {
     383        // If we're not in a search mode then search immediately
     384        if (! this.inSearchMode()) {
    328385            this.debounceTimeout = null;
    329386            await this.paletteSearchAndUpdate();
    330387            return;
    331388        }
     389
    332390        // If timer is null, reset it to 500ms and run your functions.
    333391        // Otherwise, wait until timer is cleared
    334         if (!this.debounceTimeout) {
    335             this.debounceTimeout = setTimeout(async function () {
    336                 // Reset timeout
    337                 this.debounceTimeout = null;
    338 
    339                 // Run the search function
    340                 await this.paletteSearchAndUpdate();
    341             }.bind(this), 750);
    342         }
     392
     393        // Cancel the existing timeout
     394        clearTimeout(this.debounceTimeout)
     395
     396        this.debounceTimeout = setTimeout(async function () {
     397            // Reset timeout
     398            this.debounceTimeout = null;
     399
     400            // Run the search function
     401            await this.paletteSearchAndUpdate();
     402        }.bind(this), 750);
     403    }
     404
     405    /**
     406     * Check if a string is a search mode keyword
     407     *
     408     * @param {string} inputString
     409     * @returns {boolean}
     410     */
     411    isKeyword(inputString) {
     412        return Object.keys(globalThis.turboAdmin.searchModes).includes(inputString);
     413    }
     414
     415    /**
     416     * Show the palette notice with the specified text
     417     *
     418     * @param {string} text
     419     */
     420    showPaletteNotice(text) {
     421        this.paletteNoticeElement.classList.add('active');
     422        this.paletteNoticeElement.innerText = text;
     423    }
     424
     425    /**
     426     * Hide the palette notice
     427     */
     428    hidePaletteNotice() {
     429        this.paletteNoticeElement.classList.remove('active');
    343430    }
    344431
     
    361448        }
    362449        if (e.code === 'Enter' && this.paletteShown()) {
     450            e.preventDefault();
    363451            this.doAction(this.metaPressed(e));
    364452            return;
    365453        }
     454
     455        /*
     456         * Only the actions above can be done in sub-menus.
     457         */
    366458        if (this.isSubMenuOpen()) {
    367459            return;
    368460        }
     461
     462        /*
     463         * Check for a keyword being typed and add a UI hint.
     464         */
     465        this.maybeHighlightInputKeyword(e.key);
     466
     467        /*
     468         * Tabbing looks for a search mode keyword.
     469         */
     470        if (! this.inSearchMode() && (e.code === 'Tab' || e.key === ':')) {
     471            console.log('Checking for search mode');
     472            let inputValue = this.paletteInputElement.value;
     473            if (this.isKeyword(inputValue)) {
     474                console.log('Found search mode ' + inputValue)
     475                e.preventDefault();
     476                // TODO: Work on this.
     477                await this.enterSearchMode(
     478                    globalThis.turboAdmin.searchModes[inputValue]);
     479                return;
     480            }
     481        }
     482
     483        /*
     484         * Backspace may exit us from a search mode
     485         */
     486        if (this.inSearchMode() && e.code === 'Backspace' && this.paletteInputElement.value === '') {
     487            e.preventDefault();
     488            this.leaveSearchMode();
     489            return;
     490        }
     491
    369492        await this.debouncedPaletteSearchAndUpdate();
    370493    }
    371494
     495    /**
     496     * Puts the palette into a specific search mode - used when a keyword is selected
     497     *
     498     * @param {SearchMode} searchMode
     499     */
     500    async enterSearchMode(searchMode) {
     501        console.log('Entering search mode for keyword ' + searchMode.keyword);
     502        this.backupPaletteData();
     503
     504        this.paletteData = [];
     505        this.paletteItems = [];
     506        this.itemIndex = [];
     507
     508        // Remove the notice if it's there
     509        this.hidePaletteNotice();
     510
     511        this.searchMode = searchMode;
     512        this.paletteInputElement.value = '';
     513        this.addSearchModeTag(searchMode.displayName);
     514        this.unhighlightInputKeyword();
     515        this.updatePaletteItems();
     516        // This is similar to code in paletteSearch - maybe we could extract/abstract it?
     517        if (searchMode.defaultItemsCallback !== null) {
     518            this.paletteInnerElement.classList.add('loading');
     519            const results = await searchMode.defaultItemsCallback();
     520            this.setContentItems(results);
     521            // this.injectContentItems(results);
     522            this.paletteInnerElement.classList.remove('loading');
     523        }
     524    }
     525
     526    /**
     527     * Leaves the current search mode
     528     */
     529    leaveSearchMode() {
     530        const searchMode = this.searchMode;
     531        // It's important what we set this to - see inSearchMode()
     532        this.searchMode = null;
     533        this.removeSearchModeTag();
     534        this.restorePaletteData();
     535        this.paletteInputElement.value = searchMode.keyword;
     536        this.maybeHighlightInputKeyword('');
     537        this.paletteSearchAndUpdate();
     538    }
     539
     540    /**
     541     * Backups up the palette data to a local variable so that it can be
     542     * restored later.
     543     */
     544    backupPaletteData() {
     545        this.paletteDataBackup = this.paletteData;
     546        this.paletteItemsBackup = this.paletteItems;
     547        this.paletteItemIndexBackup = this.itemIndex;
     548    }
     549
     550    /**
     551     * Restores the save palette data - does not rebuild anything
     552     */
     553    restorePaletteData() {
     554        this.paletteData = this.paletteDataBackup;
     555        this.paletteItems = this.paletteItemsBackup;
     556        this.itemIndex = this.paletteItemIndexBackup;
     557    }
     558
     559    /**
     560     * Adds the search mode tag with the specified title.
     561     *
     562     * @param {string} title
     563     */
     564    addSearchModeTag(title) {
     565        this.paletteSearchModeTag.classList.add('active');
     566        this.paletteSearchModeTag.innerText = title;
     567    }
     568
     569    /**
     570     * Removes the search mode tag
     571     */
     572    removeSearchModeTag() {
     573        this.paletteSearchModeTag.classList.remove('active');
     574    }
     575
     576    isPaletteOpen() {
     577        return this.paletteElement?.classList.contains('active');
     578    }
     579
    372580    showPalette() {
    373         this.paletteInputElement.value = '';
    374         this.paletteItemsElement.scrollTop = 0;
     581        // Bail if already shown (this can be triggered by a focus event)
     582        if (this.isPaletteOpen()) {
     583            return;
     584        }
     585
     586        this.paletteInputElement.value = '';
     587        this.paletteInputElement?.focus();
    375588        this.paletteElement?.classList.add('active');
    376         this.paletteInputElement?.focus();
     589        // This is needed in admin-bar mode otherwise it gets a weird already-scrolled thing when
     590        // the palette opens.
     591        setTimeout(() => this.paletteItemsElement.scrollTop = 0, 100);
    377592    }
    378593
     
    385600            this.closeSubMenu();
    386601        }
     602        if (this.searchMode !== null) {
     603            this.leaveSearchMode();
     604        }
    387605    }
    388606
     
    413631    setSelectedElement() {
    414632        if (this.isSubMenuOpen()) {
    415             this.paletteItemsElement?.querySelectorAll('.ta-submenu.active li.selected')?.forEach(e => e.classList.remove('selected'));
     633            this.paletteSubmenuContainerElement?.querySelectorAll('.ta-submenu li.selected')?.forEach(e => e.classList.remove('selected'));
    416634            this.selectedSubItem.classList.add('selected');
    417635        } else {
     
    489707
    490708    openSubMenu(subMenuElement) {
     709        this.paletteSubmenuContainerElement.replaceChildren(subMenuElement);
    491710        // Set height in case main menu is smaller than sub menu
    492         const subMenuHeight = subMenuElement.offsetHeight;
    493         this.paletteItemsElement.style.minHeight = subMenuHeight + "px";
    494         subMenuElement.classList.add('active');
    495 
     711        const subMenuHeight = this.paletteSubmenuContainerElement.offsetHeight;
     712        this.paletteItemsContainerElement.style.minHeight = subMenuHeight + "px";
     713        this.paletteSubmenuContainerElement.classList.add('active');
    496714
    497715        this.selectedSubItem = subMenuElement.querySelector('li');
     
    508726            subMenuElement = document.querySelector('.ta-submenu.active');
    509727        }
    510         subMenuElement.classList.remove('active');
     728        this.paletteSubmenuContainerElement.classList.remove('active');
    511729        this.selectedSubItem.classList.remove('active');
    512         this.paletteItemsElement.style.minHeight = 'auto';
     730        this.paletteItemsContainerElement.style.minHeight = 'auto';
    513731        this.selectedSubItem = null;
    514732        this.openedSubMenu = null;
     
    536754        const url = link.href;
    537755
     756        // link.href will be interpolated by the browser, so if it's empty it will be the current page
     757        // use getAttribute instead to work out if its empty
     758        if (link.getAttribute('href') === '') {
     759            return;
     760        }
     761
    538762        if ('clipboard' === link.dataset.action) {
    539763            navigator.clipboard.writeText(url);
     
    561785        // const response = await globalThis.contentApi.get('posts', { search: this.paletteInputElement.value, per_page: 100, status: ['publish', 'future', 'draft', 'pending', 'private'] });
    562786
    563         this.buildPaletteItems();
    564 
    565         if (this.paletteInputElement.value !== '') {
    566             // Reset the search to work on the new items
    567             this.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);
    568             this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map(i => i.item);
    569         }
    570 
     787        if (! this.searchMode) {
     788            this.buildPaletteItems();
     789
     790            if (this.paletteInputElement.value !== '') {
     791                // Reset the search to work on the new items
     792                this.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);
     793                this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map(i => i.item);
     794            }
     795            return;
     796        }
     797
     798        if (this.paletteInputElement.value.length === 0) {
     799            this.paletteInnerElement.classList.add('loading');
     800            let results = [];
     801            if (this.searchMode.defaultItemsCallback !== null) {
     802                results = await this.searchMode.defaultItemsCallback();
     803            }
     804            this.setContentItems(results);
     805            // this.injectContentItems(results);
     806            this.paletteInnerElement.classList.remove('loading');
     807        } else {
     808            // This is copied to enterSearchMode. Should probably be extracted.
     809            this.paletteInnerElement.classList.add('loading');
     810            const results = await this.searchMode.searchCallback(this.paletteInputElement.value);
     811            this.setContentItems(results);
     812            // this.injectContentItems(results);
     813            this.paletteInnerElement.classList.remove('loading');
     814        }
     815
     816        /**
     817         * OLD CODE BELOW
     818         */
    571819        // Content search - don't search everything!
    572         if (globalThis.contentApi.active && this.postTypes !== [] && this.paletteInputElement.value.length > 2) {
    573             this.paletteInnerElement.classList.add('loading');
    574 
    575             globalThis.contentApi.getPosts(this.paletteInputElement.value)
    576                 .then(
    577                     results => {
    578                             this.injectContentItems(results);
    579                             this.paletteInnerElement.classList.remove('loading');
    580                     }
    581                 )
    582         }
     820        // if (globalThis.contentApi.active && this.postTypes !== [] && this.paletteInputElement.value.length > 2) {
     821        //     this.paletteInnerElement.classList.add('loading');
     822
     823        //     globalThis.contentApi.getPosts(this.paletteInputElement.value)
     824        //         .then(
     825        //             results => {
     826        //                     this.injectContentItems(results);
     827        //                     this.paletteInnerElement.classList.remove('loading');
     828        //             }
     829        //         )
     830        // }
    583831    }
    584832
  • turbo-admin/tags/1.12.0/src/class-turbo-admin-wp-notices.js

    r2703739 r2835882  
    161161
    162162        noticesToHide.forEach(notice => {
    163             // Add 'inline' class otherwise WordPress might move them around!
    164             notice.classList.add('inline');
    165163            // See Toolbelt's implementation: https://github.com/BinaryMoon/wp-toolbelt/blob/dev/modules/tidy-notifications/src/js/script.js
    166164            noticesPanelInner.append(notice);
  • turbo-admin/tags/1.12.0/src/class-turbo-admin.js

    r2703739 r2835882  
    4343 * }
    4444 */
     45
    4546import TurboAdminPalette from './class-turbo-admin-palette.js';
    46 import TurboAdminMenuItem from './class-turbo-admin-menu-item.js';
    47 import Acf from './class-acf.js';
    48 import TurboAdminWpBlockEditorFullscreenKill from './class-turbo-admin-wp-block-editor-fullscreen-kill.js';
    49 import TurboAdminWpBlockEditorWelcomeGuideKill from './class-turbo-admin-wp-block-editor-welcome-guide-kill.js';
     47import TurboAdminMenuItem from './types/class-turbo-admin-menu-item.js';
     48import SearchMode from './types/class-search-mode.js';
     49import TurboAdminPlugin from './types/class-turbo-admin-plugin.js';
     50import Acf from './plugins/class-acf.js';
     51// import TurboAdminWpBlockEditorFullscreenKill from './class-turbo-admin-wp-block-editor-fullscreen-kill.js';
     52// import TurboAdminWpBlockEditorWelcomeGuideKill from './class-turbo-admin-wp-block-editor-welcome-guide-kill.js';
    5053import TurboAdminWpNotices from './class-turbo-admin-wp-notices.js';
    5154import TurboAdminListTableShortcuts from './class-list-table-shortcuts.js';
    52 import TurboAdminBarkeeper from './class-turbo-admin-barkeeper.js';
     55import TurboAdminBarkeeper from './plugins/class-turbo-admin-barkeeper.js';
     56import TurboAdminContentSearch from './plugins/class-turbo-admin-content-search.js';
     57import TurboAdminPluginSearch from './plugins/class-turbo-admin-plugins.js';
     58import TurboAdminUserSearch from './plugins/class-turbo-admin-users.js';
     59// import TurboAdminWoocommerce from './plugins/class-turbo-admin-woocommerce.js';
     60// import TurboAdminGravityForms from './plugins/class-turbo-admin-gravity-forms.js';
     61import TurboAdminMUSites from './plugins/class-turbo-admin-mu-sites.js';
     62import TurboAdminOxygenBuilder from './plugins/class-turbo-admin-oxygen-buillder.js';
    5363
    5464export default class TurboAdmin {
    5565
     66    /**
     67     * @param {*} options
     68     * @returns {TurboAdmin}
     69     */
    5670    constructor(options) {
     71        // Sometimes we get a second copy of TA running, like if the plugin is running too.
     72        // Is this case we want to skip the initialisation.
     73        this.doInit = true;
     74
    5775        if (document.getElementById('ta-command-palette-container')) {
    5876            console.log('TurboAdmin already initialised - I won\'t make a second copy!');
     77            this.doInit = false;
     78            return globalThis.turboAdmin;
     79        }
     80
     81        this.options = options;
     82        this.plugins = {};
     83
     84        // TODO: Something? What should this type be?
     85        this.searchModes = {};
     86
     87        // On the front end we set this if there is no saved menu.
     88        this.menuNeedsRefresh = false;
     89    }
     90
     91    /**
     92     * Perform initialization - this is all the things that do not need APIs to
     93     * get set up.
     94     */
     95    async init() {
     96        if (! this.doInit) {
    5997            return;
    6098        }
    6199
    62         this.options = options;
    63     }
    64 
    65     async init() {
     100        // Register all the plugins
     101        new TurboAdminBarkeeper();
     102        new TurboAdminContentSearch();
     103        new TurboAdminPluginSearch();
     104        new TurboAdminUserSearch();
     105        // new TurboAdminWoocommerce();
     106        // new TurboAdminGravityForms();
     107        new TurboAdminMUSites();
     108        new TurboAdminOxygenBuilder();
     109
    66110        // Grab the global Wp object instance
    67111        this.wp = globalThis.taWp;
    68112
    69113        this.menu = [];
     114
    70115        // Check for saved menu when on front-end
    71116        if (! this.wp.isBackend) {
     
    75120            // refresh the menu.
    76121            if (! this.wp.siteChanged) {
    77                 // Get from localStorage
    78                 const savedMenu = window.localStorage.getItem('ta-palette-data');
    79 
    80                 if (null !== savedMenu) {
    81                     // Check for .logged-in class on body
    82                     if (document.body.classList.contains('logged-in')) {
    83                         // If still logged in merge (?) the items
     122                // Check for .logged-in class on body - if logged in, we can use the saved menu,
     123                // if it exists.
     124                if (document.body.classList.contains('logged-in')) {
     125                    // Get from localStorage
     126                    const savedMenu = window.localStorage.getItem('ta-palette-data');
     127
     128                    // This attempts to see if we have cached items from the back-en
     129                    if (null === savedMenu) {
     130                        this.menuNeedsRefresh = true;
     131                    } else {
    84132                        this.menu = JSON.parse(savedMenu);
     133                        // Check if there is no "Media" item  - this should ONLY be in the back-end
     134                        if (! this.menu.some(item => item.action.endsWith('upload.php'))) {
     135                            this.menuNeedsRefresh = true;
     136                        }
     137                        // Merge (?) the items?
    85138                    }
    86139                }
     
    123176        // Initialise controls on the palette
    124177        this.turboAdminPalette = new TurboAdminPalette(this.menu, this.options);
    125 
    126         if (true === this.options['block-editor-fullscreen-disable']) {
    127             // Initialise fullscreen kill
    128             this.turboAdminFullscreenKill = new TurboAdminWpBlockEditorFullscreenKill();
    129         }
    130 
    131         if (true === this.options['block-editor-welcome-screen-kill']) {
    132             this.turboAdminWelcomeKill = new TurboAdminWpBlockEditorWelcomeGuideKill();
    133         }
     178    }
     179
     180    /**
     181     * These are initialization steps that DO needs APIs to be set up.
     182     */
     183    activatePlugins() {
     184        // Initialize all plugins
     185        Object.keys(this.plugins).forEach( plugin => {
     186            if (this.plugins[plugin].shouldActivate()) {
     187                this.plugins[plugin].activate();
     188            }
     189        })
     190
     191        // if (true === this.options['block-editor-fullscreen-disable']) {
     192        //     // Initialise fullscreen kill
     193        //     this.turboAdminFullscreenKill = new TurboAdminWpBlockEditorFullscreenKill();
     194        // }
     195
     196        // if (true === this.options['block-editor-welcome-screen-kill']) {
     197        //     this.turboAdminWelcomeKill = new TurboAdminWpBlockEditorWelcomeGuideKill();
     198        // }
    134199
    135200        if (true === this.options['list-table-keyboard-shortcuts']) {
    136201            this.turboAdminListTableShortcuts = new TurboAdminListTableShortcuts();
    137         }
    138 
    139         if (true === this.options['barkeeper']) {
    140             // In the plugin, barkeeper-state will be in... local storage(?)
    141             if ('object' !== typeof(browser)) {
    142                 this.options['barkeeper-state'] = window.localStorage.getItem('turboAdminBarkeeperState');
    143             }
    144             this.turboAdminBarkeeper = new TurboAdminBarkeeper(this.options['barkeeper-state']);
    145202        }
    146203
     
    151208    }
    152209
     210    /**
     211     * True if the plugin has been activated
     212     *
     213     * @param {string} name Name of the plugin to check for
     214     * @returns {boolean}
     215     */
     216    hasActivatedPlugin(name) {
     217        return Object.keys(this.plugins).includes(name) &&
     218            this.plugins[name].activated;
     219    }
     220
     221    /**
     222     * Gather the WordPress dashboard admin (sidebar) menu items
     223     *
     224     * @returns { TurboAdminMenuItem[] }
     225     */
    153226    getMenu() {
    154227        const items = [];
     
    184257    }
    185258
     259    /**
     260     * Adds additional menu items passed in by configuration to the
     261     * menu items list.
     262     */
    186263    addAdditionalMenuItems() {
    187264
     
    207284
    208285        // Get passed-in extraItems
     286        // Technically this is an array of {ItemDefintion} but more work needed to make that happen.
    209287        let extraItems = this.options.extraItems ?? [];
     288
     289        // Get any extra items defined by plugins
     290        const pluginKeys = Object.keys(this.plugins);
     291
     292        for (let i=0; i < pluginKeys.length; i++) {
     293            extraItems = extraItems.concat(this.plugins[pluginKeys[i]].getAdditionalItemDefinitions());
     294        }
    210295
    211296        // Merge in defaults
     
    288373                    'itemUrlFunction': (element) => element.href
    289374                },
    290                 {
    291                     'detectType': 'dom',
    292                     'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-my-sites-list .ab-submenu a',
    293                     'itemTitleFunction': (element) => "Sites: " + element.closest('.menupop').querySelector('a').innerText + ' - ' + element.innerText,
    294                     'itemUrlFunction': (element) => element.href
    295                 },
    296                 // Oxygen builder items
    297                 {
    298                     'detectType': 'dom',
    299                     'detectSelector': '#ct-edit-template-builder',
    300                     'itemTitleFunction': () => 'Edit with Oxygen',
    301                     'itemUrlFunction': (element) => element.href,
    302                     'noCache': true
    303                 },
    304                 // It's worth noting that the Oxygen Builder doesn't use a /wp-admin URL
    305                 // and so kinda appears to Turbo Admin to be a "front-end" page and it
    306                 // doesn't refresh the menu items.
    307                 {
    308                     'detectType': 'dom',
    309                     'detectSelector': '.oxygen-back-to-wp-menu .oxygen-toolbar-button-dropdown a:not(:last-of-type)',
    310                     'itemTitleFunction': (element) => 'Back to WP: ' + element.textContent,
    311                     'itemUrlFunction': (element) => {
    312                         if (element.href) {
    313                             return element.href;
    314                         } else {
    315                             let url = new URL(window.location.href);
    316                             return url.origin + url.pathname;
    317                         }
    318                     },
    319                     'noCache': true
    320                 }
    321375            ]
    322376        );
     
    359413    }
    360414
     415    /**
     416     * Builds the palette HTML and adds it to the DOM.
     417     */
    361418    addPalette() {
    362419        const container = document.createElement('div');
     
    365422        const palette = document.createElement('div');
    366423        palette.id = 'ta-command-palette';
     424        // Palette notice
     425        const paletteNotice = document.createElement('div');
     426        paletteNotice.id = 'ta-command-palette-notice';
     427        // Tab notice
     428        const tabNotice = document.createElement('div');
     429        tabNotice.id = 'ta-command-palette-tab-notice';
     430        // Tab notice text
     431        const tabNoticeText = document.createElement('span');
     432        tabNoticeText.id = 'ta-command-palette-tab-notice-text';
     433        // Tab notice "button"
     434        const tabNoticeButton = document.createElement('span');
     435        tabNoticeButton.id = 'ta-command-palette-tab-notice-button';
     436        tabNoticeButton.innerText = 'Tab';
    367437        // Input field
    368438        const input = document.createElement('input');
     
    372442        // Set this to stop stuff trying to fill it.
    373443        input.setAttribute('autocomplete', 'off');
     444        // Search mode tag
     445        const searchModeTag = document.createElement('div');
     446        searchModeTag.id = 'ta-command-palette-search-mode-tag';
     447        // List container (needed to contain the main list and the submenu list)
     448        const listContainer = document.createElement('div');
     449        listContainer.id = "ta-command-palette-items-container";
    374450        // List
    375451        const list = document.createElement('ul');
    376452        list.id = "ta-command-palette-items";
     453        // Sub-menu list
     454        const submenuContainer = document.createElement('div');
     455        submenuContainer.id = "ta-command-palette-submenu-container";
    377456        // Join it all up
    378457        container.appendChild(palette);
     458        palette.appendChild(searchModeTag);
     459        palette.appendChild(paletteNotice);
     460        tabNotice.appendChild(tabNoticeText);
     461        tabNotice.appendChild(tabNoticeButton);
     462        palette.appendChild(tabNotice);
    379463        palette.appendChild(input);
    380         palette.appendChild(list);
     464        listContainer.appendChild(list);
     465        listContainer.appendChild(submenuContainer);
     466        palette.appendChild(listContainer);
    381467
    382468        if (document.getElementById('wpadminbar') && this.options['admin-bar-search'] === true) {
     
    395481            placeholder.addEventListener('click', e => input.focus());
    396482
    397             palette.insertBefore( placeholder, list );
     483            palette.insertBefore( placeholder, listContainer );
    398484        } else {
    399485            // Container
     
    402488    }
    403489
     490    /**
     491     * Register a plugin with Turbo Admin
     492     *
     493     * @param {TurboAdminPlugin} plugin
     494     */
     495    registerPlugin(plugin) {
     496        console.log('Registering plugin ' + plugin.name);
     497        this.plugins[plugin.name] = plugin;
     498    }
     499
     500    /**
     501     * Register a palette search mode and its associated plugin
     502     *
     503     * this is usually bound to the searchMode, so
     504     *
     505     * @param {SearchMode} searchMode
     506     */
     507    registerSearchMode(searchMode) {
     508        console.log('Registering search mode with keyword ' + searchMode.keyword);
     509        // Don't use `this` as we are bound!
     510        globalThis.turboAdmin.searchModes[searchMode.keyword] = searchMode;
     511    }
     512
     513    /**
     514     * Returns a string representation of the palette's keyboard shortcut
     515     *
     516     * @returns { String }
     517     */
    404518    buildShortcutKeysString () {
    405519        let keysString = '';
     
    418532            keysString += 'Shift-';
    419533        }
    420         keysString += shortcut.key.toUpperCase();
     534        keysString += shortcut.key;
    421535        return keysString;
    422536    }
  • turbo-admin/tags/1.12.0/src/main.js

    r2703739 r2835882  
    11import TurboAdmin from './class-turbo-admin.js';
    2 import ContentApi from './class-content-api.js';
     2import ContentApi from './apis/class-content-api.js';
    33import Wp from './class-wp.js';
    44import TurboAdminWpNotices from './class-turbo-admin-wp-notices.js';
     5import WoocommerceApi from './apis/class-woocommerce-api.js';
     6import GravityFormsApi from './apis/class-gravity-forms-api.js';
    57
    68const taStorageKey = 'turbo-admin-settings';
     9
     10// Use this to clear storage
     11// browser.storage.local.remove(taStorageKey).then();
    712
    813// Note that in the extension, the globalThis is not the browser's global scope,
     
    1015async function taInit(settings) {
    1116
     17    if (typeof(globalThis.turboAdmin) !== 'undefined') {
     18        // Already initialised for some reason
     19        return;
     20    }
    1221    globalThis.turboAdmin = null;
    1322
     
    1928
    2029    globalThis.turboAdminOptions = settings[taStorageKey];
     30
     31    console.log('Preparing Turbo Admin');
    2132
    2233    // Get Wp stuff ready
     
    3142    globalThis.contentApi = new ContentApi();
    3243    await globalThis.contentApi.discoverApiRoot();
     44    await globalThis.contentApi.discoverPostTypes();
     45    globalThis.woocommerceApi = new WoocommerceApi();
     46    globalThis.gravityFormsApi = new GravityFormsApi();
    3347
    3448    console.log('Turbo Admin: Content API is initialised');
    3549
    3650    globalThis.turboAdmin = new TurboAdmin(globalThis.turboAdminOptions);
     51    await globalThis.turboAdmin.init();
    3752
    38     await globalThis.turboAdmin.init();
     53
     54
     55    // This needs all the APIs to be ready
     56    await globalThis.turboAdmin.activatePlugins();
    3957
    4058    if (settings[taStorageKey]['hide-notices']) {
  • turbo-admin/tags/1.12.0/turbo-admin.css

    r2703739 r2835882  
    3939    top: calc( 10vh + 20px );
    4040    left: 50%;
    41     overflow: hidden;
     41    /* overflow: hidden; */
     42    overflow: visible;
    4243    transform: translateX(-50%);
    4344    opacity: 0;
    4445    transition: top 0.3s, opacity 0.3s;
     46    -webkit-font-smoothing: subpixel-antialiased; /* This normalises how the front and back-ends look */
    4547}
    4648
     
    5052}
    5153
    52 #ta-command-palette-input {
     54/*
     55 * We need to override "#wpadminbar *" in admin-bar mode, so many styles have a #wpadminbar prefix
     56 * as well as a regular selector.
     57 */
     58#ta-command-palette-tab-notice,
     59#wpadminbar #ta-command-palette-tab-notice {
     60    display: block;
     61    color: white;
     62    position: absolute;
     63    right: 24px;
     64    font-size: 12px;
     65    line-height: 1;
     66    top: 29px;
     67    opacity: 0;
     68    transition: opacity 0.3s;
     69    z-index: 20;
     70}
     71
     72#ta-command-palette-tab-notice.active,
     73#wpadminbar #ta-command-palette-tab-notice.active {
     74    opacity: 1;
     75}
     76
     77#ta-command-palette-tab-notice-button,
     78#wpadminbar #ta-command-palette-tab-notice-button {
     79    display: inline-block;
     80    color: white;
     81    border: 1px solid white;
     82    position: relative;
     83    font-size: 12px;
     84    border-radius: 4px;
     85    padding: 2px 4px;
     86    margin-left: 6px;
     87}
     88
     89#ta-command-palette-search-mode-tag,
     90#wpadminbar #ta-command-palette-search-mode-tag,
     91#ta-command-palette-notice,
     92#wpadminbar #ta-command-palette-notice {
     93    color: white;
     94    font-size: 16px;
     95    border-radius: 6px;
     96    background-color:rgb(51,51,51);
     97    position: absolute;
     98    left: 20px;
     99    top: 16px;
     100    padding: 4px 8px;
     101    line-height: 1;
     102    opacity: 0;
     103    transition: opacity 0.3s, top 0.3s, transform 0.3s;
     104}
     105
     106#ta-command-palette-notice,
     107#wpadminbar #ta-command-palette-notice {
     108    top: 16px;
     109    left: auto;
     110    right: 20px;
     111}
     112
     113#ta-command-palette-search-mode-tag.active,
     114#ta-command-palette-notice.active {
     115    top: -18px;
     116    left: 20px;
     117    padding: 6px 10px;
     118}
     119
     120#ta-command-palette-notice.active {
     121    left: auto;
     122    right: 20px;
     123}
     124
     125#ta-command-palette-search-mode-tag.active,
     126#ta-command-palette-notice.active,
     127#wpadminbar #ta-command-palette-search-mode-tag.active,
     128#wpadminbar #ta-command-palette-notice.active {
     129    opacity: 1;
     130}
     131
     132#wpadminbar #ta-command-palette-notice {
     133    font-size: 13px;
     134    top: 27px;
     135    right: 0;
     136}
     137
     138#wpadminbar #ta-command-palette-search-mode-tag {
     139    font-size: 14px;
     140    top: 2px;
     141    left: 0;
     142    transform: translateX( -100% );
     143    background-color: #666;
     144}
     145#wpadminbar #ta-command-palette-search-mode-tag:before {
     146    content: 'Search for ';
     147}
     148#wpadminbar #ta-command-palette-search-mode-tag.active {
     149    top: 2px;
     150    transform: translateX( calc( -100% - 5px ) );
     151    opacity: 1;
     152}
     153
     154
     155#ta-command-palette-input,
     156#wpadminbar #ta-command-palette-input {
    53157    font-family: inherit;
    54158    background-color: #333;
     
    63167    color: #FFF;
    64168    outline: none;
     169    z-index: 10; /* To hide the search-mode tag */
    65170}
    66171
     
    74179}
    75180
    76 #ta-command-palette:after {
     181#ta-command-palette:after,
     182#wpadminbar #ta-command-palette:after {
    77183    display: none;
    78184    content: '';
    79185    position: absolute;
     186    z-index: 20;
    80187    top: 28px;
    81188    right: 24px;
     
    90197}
    91198
    92 #ta-command-palette.loading:after {
     199#ta-command-palette.loading:after,
     200#wpadminbar #ta-command-palette.loading:after {
    93201    background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg' data-reactroot=''%3E%3Cpath fill='white' d='M12 2C11.1716 2 10.5 2.67157 10.5 3.5C10.5 4.32843 11.1716 5 12 5C12.8284 5 13.5 4.32843 13.5 3.5C13.5 2.67157 12.8284 2 12 2Z' clip-rule='evenodd' fill-rule='evenodd' undefined='1'%3E%3C/path%3E%3Cpath fill='white' d='M12 19C11.1716 19 10.5 19.6716 10.5 20.5C10.5 21.3284 11.1716 22 12 22C12.8284 22 13.5 21.3284 13.5 20.5C13.5 19.6716 12.8284 19 12 19Z' clip-rule='evenodd' fill-rule='evenodd' undefined='1'%3E%3C/path%3E%3Cpath fill='white' d='M7.75 3.14001C6.92157 3.14001 6.25 3.81159 6.25 4.64001C6.25 5.46844 6.92157 6.14001 7.75 6.14001C8.57843 6.14001 9.25 5.46844 9.25 4.64001C9.25 3.81159 8.57843 3.14001 7.75 3.14001Z' clip-rule='evenodd' fill-rule='evenodd' undefined='1'%3E%3C/path%3E%3Cpath fill='white' d='M16.25 17.86C15.4216 17.86 14.75 18.5316 14.75 19.36C14.75 20.1884 15.4216 20.86 16.25 20.86C17.0784 20.86 17.75 20.1884 17.75 19.36C17.75 18.5316 17.0784 17.86 16.25 17.86Z' clip-rule='evenodd' fill-rule='evenodd' undefined='1'%3E%3C/path%3E%3Cpath fill='white' d='M4.64001 6.25C3.81159 6.25 3.14001 6.92157 3.14001 7.75C3.14001 8.57843 3.81159 9.25 4.64001 9.25C5.46844 9.25 6.14001 8.57843 6.14001 7.75C6.14001 6.92157 5.46844 6.25 4.64001 6.25Z' clip-rule='evenodd' fill-rule='evenodd' undefined='1'%3E%3C/path%3E%3Cpath fill='white' d='M19.36 14.75C18.5316 14.75 17.86 15.4216 17.86 16.25C17.86 17.0784 18.5316 17.75 19.36 17.75C20.1884 17.75 20.86 17.0784 20.86 16.25C20.86 15.4216 20.1884 14.75 19.36 14.75Z' clip-rule='evenodd' fill-rule='evenodd' undefined='1'%3E%3C/path%3E%3Cpath fill='white' d='M3.5 10.5C2.67157 10.5 2 11.1716 2 12C2 12.8284 2.67157 13.5 3.5 13.5C4.32843 13.5 5 12.8284 5 12C5 11.1716 4.32843 10.5 3.5 10.5Z' clip-rule='evenodd' fill-rule='evenodd' undefined='1'%3E%3C/path%3E%3Cpath fill='white' d='M20.5 10.5C19.6716 10.5 19 11.1716 19 12C19 12.8284 19.6716 13.5 20.5 13.5C21.3284 13.5 22 12.8284 22 12C22 11.1716 21.3284 10.5 20.5 10.5Z' clip-rule='evenodd' fill-rule='evenodd' undefined='1'%3E%3C/path%3E%3Cpath fill='white' d='M4.64001 14.75C3.81159 14.75 3.14001 15.4216 3.14001 16.25C3.14001 17.0784 3.81159 17.75 4.64001 17.75C5.46844 17.75 6.14001 17.0784 6.14001 16.25C6.14001 15.4216 5.46844 14.75 4.64001 14.75Z' clip-rule='evenodd' fill-rule='evenodd' undefined='1'%3E%3C/path%3E%3Cpath fill='white' d='M19.36 6.25C18.5316 6.25 17.86 6.92157 17.86 7.75C17.86 8.57843 18.5316 9.25 19.36 9.25C20.1884 9.25 20.86 8.57843 20.86 7.75C20.86 6.92157 20.1884 6.25 19.36 6.25Z' clip-rule='evenodd' fill-rule='evenodd' undefined='1'%3E%3C/path%3E%3Cpath fill='white' d='M7.75 17.86C6.92157 17.86 6.25 18.5316 6.25 19.36C6.25 20.1884 6.92157 20.86 7.75 20.86C8.57843 20.86 9.25 20.1884 9.25 19.36C9.25 18.5316 8.57843 17.86 7.75 17.86Z' clip-rule='evenodd' fill-rule='evenodd' undefined='1'%3E%3C/path%3E%3Cpath fill='white' d='M16.25 3.14001C15.4216 3.14001 14.75 3.81159 14.75 4.64001C14.75 5.46844 15.4216 6.14001 16.25 6.14001C17.0784 6.14001 17.75 5.46844 17.75 4.64001C17.75 3.81159 17.0784 3.14001 16.25 3.14001Z' clip-rule='evenodd' fill-rule='evenodd' undefined='1'%3E%3C/path%3E%3C/svg%3E%0A");
    94202    display: block;
    95203}
    96204
    97 #ta-command-palette-items {
     205#ta-command-palette-items-container,
     206#wpadminbar #ta-command-palette-items-container {
     207    position: relative;
     208    background-color: #000;
     209    font-size: inherit;
     210    line-height: 1.3;
     211    display: block;
     212    margin: 0;
     213    padding: 0;
     214    width: 100%;
     215    height: 80%;
     216    max-height: 300px;
     217    color: #FFF;
     218    overflow: hidden;
     219}
     220
     221#ta-command-palette-items,
     222#ta-command-palette-submenu-container,
     223#wpadminbar #ta-command-palette-items,
     224#wpadminbar #ta-command-palette-submenu-container {
    98225    position: relative;
    99226    background-color: #000;
     
    105232    list-style-type: none;
    106233    width: 100%;
    107     height: 80%;
    108     max-height: 300px;
     234    height: 100%;
     235    max-height: 300px;
    109236    overflow-x: hidden;
    110237    overflow-y: scroll;
    111     color: #FFF;
    112238    scrollbar-width: thin;          /* "auto" or "thin" */
    113239    scrollbar-color: #444 #000;   /* scroll thumb and track */
    114240}
    115 #ta-command-palette-items::-webkit-scrollbar {
     241
     242#ta-command-palette-submenu-container,
     243#wpadminbar #ta-command-palette-submenu-container {
     244    position: absolute;
     245    top: 0;
     246    left: 100%;
     247    height: auto;
     248    min-height: 100%;
     249    transition: left 0.3s;
     250}
     251
     252#ta-command-palette-submenu-container.active,
     253#wpadminbar #ta-command-palette-submenu-container.active {
     254    left: 0;
     255}
     256
     257#ta-command-palette-items::-webkit-scrollbar,
     258#ta-command-palette-submenu-container::-webkit-scrollbar {
    116259  width: 6px;               /* width of the entire scrollbar */
    117260}
    118261
    119 #ta-command-palette-items::-webkit-scrollbar-track {
     262#ta-command-palette-items::-webkit-scrollbar-track,
     263#ta-command-palette-submenu-container::-webkit-scrollbar {
    120264  background: #000;        /* color of the tracking area */
    121265}
    122266
    123 #ta-command-palette-items::-webkit-scrollbar-thumb {
     267#ta-command-palette-items::-webkit-scrollbar-thumb,
     268#ta-command-palette-submenu-container::-webkit-scrollbar {
    124269  background-color: #444;    /* color of the scroll thumb */
    125270  border-radius: 20px;       /* roundness of the scroll thumb */
     
    127272}
    128273
    129 #ta-command-palette li {
     274#ta-command-palette li,
     275#wpadminbar #ta-command-palette li {
    130276    display: block;
    131277    margin: 0 !important;
     
    133279}
    134280
    135 #ta-command-palette a {
     281#ta-command-palette a,
     282#wpadminbar #ta-command-palette a {
    136283    display: flex;
    137284    flex-shrink: 0;
     
    182329}
    183330
     331/* Submenu items are all hidden - the markup is copied to the submenu container */
    184332#ta-command-palette .ta-submenu {
     333    display: none;
     334}
     335#ta-command-palette #ta-command-palette-submenu-container .ta-submenu {
     336    display: block;
     337}
     338
     339/* #ta-command-palette .ta-submenu {
    185340    position: absolute;
    186341    right: -100%;
     
    195350#ta-command-palette .ta-submenu.active {
    196351    right: 0;
    197 }
     352} */
    198353
    199354#ta-command-palette .ta-submenu-title {
     
    216371    width: auto;
    217372    height: auto;
     373    padding: 3px 5px 3px 5px;
    218374    position: relative;
    219375    background-color: none;
    220376    transition: none;
     377    overflow: visible;
    221378}
    222379
     
    239396    opacity: 1;
    240397    transition: none;
    241     padding: 3px 5px 3px 5px;
     398    padding: 0;
    242399    background-color: #1d2327;
    243400}
    244401
     402#wpadminbar #ta-command-palette-tab-notice {
     403    top: 3px;
     404    right: 10px;
     405}
     406#wpadminbar #ta-command-palette-tab-notice-text {
     407    display: none;
     408}
    245409#wpadminbar #ta-command-palette-input {
    246410    line-height: 1.6;
     
    254418#wpadminbar #ta-shortcut-key-placeholder {
    255419    position: absolute;
    256     top: 8px;
     420    top: 6px;
    257421    left: 12px;
     422    z-index: 100;
    258423}
    259424
     
    280445    height: auto;
    281446}
     447
     448#wpadminbar #ta-command-palette-submenu-container {
     449    background-color: #1d2327;
     450    z-index: 100000;
     451}
     452
    282453#wpadminbar #ta-command-palette-items .ta-submenu {
    283454    background-color: #1d2327;
    284455}
     456
    285457#wpadminbar #ta-command-palette-items .ta-has-child-menu.selected {
    286458    z-index: 9999999; /* Needs to be higher than #ta-command-palette-container */
     
    304476#wpadminbar #ta-command-palette-container.active #ta-command-palette-items {
    305477    padding-top: 8px;
    306     max-height: 400px;
     478    max-height: 300px;
    307479    opacity: 1;
    308480}
  • turbo-admin/trunk/dist/main.min.js

    r2703739 r2835882  
    808808  var import_fuse_6_4_6 = __toModule(require_fuse_6_4_6());
    809809
    810   // src/class-turbo-admin-menu-item.js
     810  // src/types/class-turbo-admin-menu-item.js
    811811  var TurboAdminMenuItem = class {
     812    title = "";
     813    action = "";
     814    parentTitle = "";
     815    noCache = false;
    812816    constructor(title, action, parentTitle, noCache = false) {
    813817      this.title = title;
     
    862866  var class_storage_default = Storage;
    863867
    864   // src/class-content-api.js
     868  // src/apis/class-content-api.js
    865869  var ContentApi = class {
    866870    constructor() {
    867871      this.active = false;
    868872      this.store = new class_storage_default();
     873      this.postTypes = [];
    869874      this.cache = {};
    870875    }
    871876    async discoverApiRoot() {
     877      console.log("Discovering API root");
    872878      let wpApiSettings = null;
    873879      this.storageKey = "wpApiSettings." + globalThis.taWp.home;
     
    902908        return;
    903909      }
     910      console.log("API Route Discovery failed");
     911    }
     912    async discoverPostTypes() {
     913      console.log("Discovering post types");
     914      if (!this.active) {
     915        console.log("Not active");
     916        this.postTypes = [];
     917        return;
     918      }
     919      this.postTypes = await this.getPostTypes();
     920      console.log("Discovered post types: ", this.postTypes);
    904921    }
    905922    userLoggedIn() {
     
    934951      }
    935952    }
    936     types() {
    937       return globalThis.turboAdmin.turboAdminPalette.postTypes;
    938     }
    939     async getPosts(searchString) {
    940       if (this.cache[searchString] !== void 0) {
    941         return this.cache[searchString];
     953    async getPostTypes() {
     954      if (this.cache["postsTypes"] !== void 0) {
     955        return this.cache["postTypes"];
     956      }
     957      const response = await this.get("types");
     958      const result = await response.json();
     959      this.cache["postTypes"] = result;
     960      return result;
     961    }
     962    async getPosts(searchString, postType = "any") {
     963      const cacheKey = `posts-${postType}-${searchString}`;
     964      if (this.cache[cacheKey] !== void 0) {
     965        return this.cache[cacheKey];
    942966      }
    943967      const response = await this.get("search", {
     
    945969        per_page: 100,
    946970        type: "post",
    947         subtype: "any"
     971        subtype: postType
    948972      });
    949973      const result = await response.json();
    950       this.cache[searchString] = result;
     974      this.cache[cacheKey] = result;
     975      return result;
     976    }
     977    async doesPostExist(postId) {
     978      if (this.cache["post-" + postId] !== void 0) {
     979        return this.cache["post-" + postId];
     980      }
     981      const init = {
     982        method: "GET",
     983        headers: {},
     984        mode: "cors",
     985        cache: "no-store",
     986        credentials: "include"
     987      };
     988      const response = await fetch(`${globalThis.taWp.siteUrl}/post.php?post=${postId}&action=edit`, init);
     989      this.cache["post-" + postId] = response;
     990      return response?.status === 200;
     991    }
     992    async getPlugins(searchString) {
     993      if (this.cache["plugins-" + searchString] !== void 0) {
     994        return this.cache["plugins-" + searchString];
     995      }
     996      let requestOptions = {};
     997      if (searchString) {
     998        requestOptions.search = searchString;
     999      }
     1000      const response = await this.get("plugins", requestOptions);
     1001      const result = await response.json();
     1002      this.cache["plugins-" + searchString] = result;
     1003      return result;
     1004    }
     1005    async getUsers(searchString) {
     1006      if (this.cache["users-" + searchString] !== void 0) {
     1007        return this.cache["users-" + searchString];
     1008      }
     1009      const response = await this.get("users", {
     1010        search: searchString,
     1011        per_page: 100,
     1012        context: "edit"
     1013      });
     1014      const result = await response.json();
     1015      this.cache["users-" + searchString] = result;
    9511016      return result;
    9521017    }
     
    9561021        headers: {},
    9571022        mode: "cors",
    958         cache: "no-store"
     1023        cache: "no-store",
     1024        credentials: "include"
    9591025      };
    9601026      if (this.apiNonce) {
     
    9621028      }
    9631029      const params = this.makeParamString(data);
    964       const response = await fetch(`${this.apiBase}${path}/?${params}`);
     1030      const response = await fetch(`${this.apiBase}${path}/?${params}`, init);
     1031      if (response.status < 200 || response.status >= 300) {
     1032        globalThis.turboAdmin.turboAdminPalette.showPaletteNotice("WordPress API Error. Try visiting the dashboard to refresh things.");
     1033      }
    9651034      return response;
    9661035    }
    9671036  };
    9681037  var class_content_api_default = ContentApi;
     1038
     1039  // src/types/class-submenu-item.js
     1040  var SubmenuItem = class {
     1041    title;
     1042    url;
     1043    attributes = [];
     1044    constructor(title, url) {
     1045      this.title = title;
     1046      this.url = url;
     1047    }
     1048    addAttribute(name, value) {
     1049      this.attributes.push({
     1050        name,
     1051        value
     1052      });
     1053    }
     1054  };
     1055  var class_submenu_item_default = SubmenuItem;
     1056
     1057  // src/types/class-content-item.js
     1058  var ContentItem = class {
     1059    title = "";
     1060    subtype = "";
     1061    url = "";
     1062    submenuItems = [];
     1063  };
     1064  var class_content_item_default = ContentItem;
     1065
     1066  // src/types/class-search-mode.js
     1067  var SearchMode = class {
     1068    keyword = "";
     1069    displayName = "";
     1070    searchCallback;
     1071    defaultItemsCallback = null;
     1072    constructor(keyword, displayName, searchCallback, defaultItemsCallback = null) {
     1073      this.keyword = keyword;
     1074      this.displayName = displayName;
     1075      this.searchCallback = searchCallback;
     1076      this.defaultItemsCallback = defaultItemsCallback;
     1077    }
     1078  };
     1079  var class_search_mode_default = SearchMode;
    9691080
    9701081  // src/class-turbo-admin-palette.js
     
    9761087      this.paletteInnerElement = document.getElementById("ta-command-palette");
    9771088      this.paletteInputElement = document.getElementById("ta-command-palette-input");
     1089      this.paletteItemsContainerElement = document.getElementById("ta-command-palette-items-container");
    9781090      this.paletteItemsElement = document.getElementById("ta-command-palette-items");
     1091      this.paletteSubmenuContainerElement = document.getElementById("ta-command-palette-submenu-container");
     1092      this.paletteSearchModeTag = document.getElementById("ta-command-palette-search-mode-tag");
     1093      this.paletteSearchModeTabNotice = document.getElementById("ta-command-palette-tab-notice");
     1094      this.paletteSearchModeTabNoticeText = document.getElementById("ta-command-palette-tab-notice-text");
     1095      this.paletteNoticeElement = document.getElementById("ta-command-palette-notice");
     1096      if (globalThis.turboAdmin.menuNeedsRefresh) {
     1097        this.showPaletteNotice("Menu needs refreshing. Visit the Dashboard to refresh.");
     1098      }
     1099      this.profileLinkElem = document.getElementById("wp-admin-bar-edit-profile");
     1100      this.profileLink = null;
     1101      if (this.profileLinkElem) {
     1102        this.profileLink = this.profileLinkElem.querySelector("a").href;
     1103      }
    9791104      this.paletteData = paletteData;
    980       this.postTypes = [];
    981       this.fetchPostTypes();
     1105      this.paletteDataBackup = null;
     1106      this.paletteItemsBackup = null;
     1107      this.paletteItemIndexBackup = null;
     1108      this.searchMode = null;
    9821109      this.paletteItems = [];
    9831110      this.itemIndex = {};
     
    10171144      return this.isMac() ? e.metaKey : e.ctrlKey;
    10181145    }
    1019     fetchPostTypes() {
    1020       if (!globalThis.contentApi.active) {
    1021         this.postTypes = [];
    1022         return;
    1023       }
    1024       globalThis.contentApi.get("types").then((response) => {
    1025         response.json().then((types) => {
    1026           this.postTypes = types;
    1027         });
    1028       });
     1146    inSearchMode() {
     1147      return this.searchMode !== null;
    10291148    }
    10301149    buildPaletteItems() {
     
    10541173      return Boolean(this.itemIndex[url]);
    10551174    }
    1056     injectContentItems(contentItems) {
     1175    setContentItems(contentItems) {
     1176      this.paletteItems = [];
     1177      this.itemIndex = [];
     1178      this.injectContentItems(contentItems, false);
     1179    }
     1180    injectContentItems(contentItems, andRunSearch = true) {
    10571181      console.log("Injecting items");
    1058       const profileLinkElem = document.getElementById("wp-admin-bar-edit-profile");
    1059       let profileLink = null;
    1060       if (profileLinkElem) {
    1061         profileLink = profileLinkElem.querySelector("a").href;
    1062       }
    1063       let oxygenLinkElem = document.getElementById("toplevel_page_ct_dashboard_page");
    1064       if (!oxygenLinkElem) {
    1065         oxygenLinkElem = document.getElementById("wp-admin-bar-oxygen_admin_bar_menu");
    1066       }
    1067       if (!oxygenLinkElem) {
    1068         oxygenLinkElem = Number(window.localStorage.getItem("ta-has-oxygen-builder"));
    1069       }
    1070       window.localStorage.setItem("ta-has-oxygen-builder", Boolean(oxygenLinkElem) ? "1" : "0");
    10711182      if (contentItems.length > 0) {
    1072         contentItems.forEach((item) => {
    1073           const itemTitle = item.title;
    1074           const itemType = item.subtype;
    1075           const itemUrl = item.url;
    1076           if (this.contentItemExists(itemUrl)) {
    1077             console.log("Not adding duplicate");
    1078             return;
     1183        contentItems.forEach(this.injectItem.bind(this));
     1184      }
     1185      if (andRunSearch) {
     1186        this.paletteFuse = new import_fuse_6_4_6.default(this.paletteItems, this.paletteFuseOptions);
     1187        this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map((i) => i.item);
     1188      }
     1189      this.updatePaletteItems();
     1190    }
     1191    injectItem(item) {
     1192      const itemTitle = item.title;
     1193      const itemType = item.subtype;
     1194      const itemUrl = item.url;
     1195      if (this.contentItemExists(itemUrl)) {
     1196        console.log("Not adding duplicate");
     1197        return;
     1198      }
     1199      let title = itemTitle;
     1200      if (itemType) {
     1201        const itemTypeName = globalThis.contentApi.postTypes[itemType] ? globalThis.contentApi.postTypes[itemType].name : itemType;
     1202        title += ` (${itemTypeName})`;
     1203      }
     1204      const li = document.createElement("li");
     1205      const a = document.createElement("a");
     1206      let subMenu = null;
     1207      if (item.submenuItems.length > 0) {
     1208        subMenu = document.createElement("div");
     1209        const subMenuTitle = document.createElement("div");
     1210        const subMenuItems = document.createElement("ul");
     1211        subMenu.classList.add("ta-submenu");
     1212        subMenuTitle.classList.add("ta-submenu-title");
     1213        subMenuTitle.textContent = this.htmlDecode(itemTitle);
     1214        subMenuItems.classList.add("ta-submenu-items");
     1215        subMenu.appendChild(subMenuTitle);
     1216        for (let i = 0; i < item.submenuItems.length; i++) {
     1217          const subMenuItem = item.submenuItems[i];
     1218          const subMenuListItem = document.createElement("li");
     1219          const subMenuLink = document.createElement("a");
     1220          subMenuLink.innerText = subMenuItem.title;
     1221          subMenuLink.href = subMenuItem.url;
     1222          for (let a2 = 0; a2 < subMenuItem.attributes.length; a2++) {
     1223            subMenuLink.setAttribute(subMenuItem.attributes[a2].name, subMenuItem.attributes[a2].value);
    10791224          }
    1080           const itemTypeName = this.postTypes[itemType] ? this.postTypes[itemType].name : itemType;
    1081           const title = `${itemTitle} (${itemTypeName})`;
    1082           const li = document.createElement("li");
    1083           const a = document.createElement("a");
    1084           const subMenu = document.createElement("div");
    1085           const subMenuTitle = document.createElement("div");
    1086           const subMenuItems = document.createElement("ul");
    1087           subMenu.classList.add("ta-submenu");
    1088           subMenuTitle.classList.add("ta-submenu-title");
    1089           subMenuTitle.textContent = this.htmlDecode(itemTitle);
    1090           subMenuItems.classList.add("ta-submenu-items");
    1091           subMenu.appendChild(subMenuTitle);
    1092           subMenu.appendChild(subMenuItems);
    1093           const subMenuItem1 = document.createElement("li");
    1094           const subMenuLink1 = document.createElement("a");
    1095           subMenuLink1.innerText = "View";
    1096           subMenuLink1.href = itemUrl;
    1097           subMenuItem1.appendChild(subMenuLink1);
    1098           subMenuItems.appendChild(subMenuItem1);
    1099           if (profileLink) {
    1100             const editLink = profileLink.replace("profile.php", `post.php?post=${item.id}&action=edit`);
    1101             const subMenuItem2 = document.createElement("li");
    1102             const subMenuLink2 = document.createElement("a");
    1103             subMenuLink2.innerText = "Edit";
    1104             subMenuLink2.href = editLink;
    1105             subMenuItem2.appendChild(subMenuLink2);
    1106             subMenuItems.appendChild(subMenuItem2);
    1107           }
    1108           if (oxygenLinkElem) {
    1109             const oxygenLink = globalThis.taWp.home + `?page_id=${item.id}&ct_builder=true&ct_inner=true`;
    1110             const subMenuItem32 = document.createElement("li");
    1111             const subMenuLink32 = document.createElement("a");
    1112             subMenuLink32.innerText = "Edit with Oxygen";
    1113             subMenuLink32.href = oxygenLink;
    1114             subMenuItem32.appendChild(subMenuLink32);
    1115             subMenuItems.appendChild(subMenuItem32);
    1116           }
    1117           const subMenuItem3 = document.createElement("li");
    1118           const subMenuLink3 = document.createElement("a");
    1119           subMenuLink3.innerText = "Copy link";
    1120           subMenuLink3.href = itemUrl;
    1121           subMenuLink3.setAttribute("data-action", "clipboard");
    1122           subMenuItem3.appendChild(subMenuLink3);
    1123           subMenuItems.appendChild(subMenuItem3);
    1124           li.classList.add("ta-has-child-menu");
    1125           li.appendChild(a);
    1126           li.appendChild(subMenu);
    1127           a.href = itemUrl;
    1128           a.innerHTML = title;
    1129           this.addPaletteListItem(li);
    1130         });
    1131       }
    1132       this.paletteFuse = new import_fuse_6_4_6.default(this.paletteItems, this.paletteFuseOptions);
    1133       this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map((i) => i.item);
    1134       this.updatePaletteItems();
     1225          subMenuListItem.appendChild(subMenuLink);
     1226          subMenuItems.appendChild(subMenuListItem);
     1227        }
     1228        subMenu.appendChild(subMenuItems);
     1229        li.classList.add("ta-has-child-menu");
     1230      }
     1231      a.href = itemUrl;
     1232      a.innerHTML = title;
     1233      li.appendChild(a);
     1234      if (subMenu !== null) {
     1235        li.appendChild(subMenu);
     1236      }
     1237      this.addPaletteListItem(li);
    11351238    }
    11361239    async handleGlobalKey(e) {
     
    11431246          this.showPalette();
    11441247        }
     1248        return;
    11451249      }
    11461250      if (e.code === "Escape" && this.paletteShown()) {
    11471251        if (this.isSubMenuOpen()) {
    11481252          this.closeSubMenu();
     1253        } else if (this.inSearchMode()) {
     1254          this.leaveSearchMode();
    11491255        } else {
    11501256          this.hidePalette();
    11511257        }
     1258        return;
    11521259      }
    11531260      if (this.paletteShown()) {
     
    11641271      return keysPressed;
    11651272    }
     1273    maybeHighlightInputKeyword(newKey) {
     1274      if (this.inSearchMode()) {
     1275        return;
     1276      }
     1277      let newInputValue = this.paletteInputElement.value;
     1278      if (newKey.length === 1) {
     1279        newInputValue += newKey;
     1280      }
     1281      if (newKey === "Backspace") {
     1282        newInputValue = newInputValue.slice(0, -1);
     1283      }
     1284      if (this.isKeyword(newInputValue)) {
     1285        this.paletteSearchModeTabNoticeText.innerText = `Search for ${newInputValue}`;
     1286        this.paletteSearchModeTabNotice.classList.add("active");
     1287      } else {
     1288        this.unhighlightInputKeyword();
     1289      }
     1290    }
     1291    unhighlightInputKeyword() {
     1292      this.paletteSearchModeTabNotice.classList.remove("active");
     1293    }
    11661294    async debouncedPaletteSearchAndUpdate() {
    1167       if (this.paletteInputElement.value !== "" && this.paletteInputElement.value.length <= 2 || this.postTypes === []) {
     1295      if (!this.inSearchMode()) {
    11681296        this.debounceTimeout = null;
    11691297        await this.paletteSearchAndUpdate();
    11701298        return;
    11711299      }
    1172       if (!this.debounceTimeout) {
    1173         this.debounceTimeout = setTimeout(async function() {
    1174           this.debounceTimeout = null;
    1175           await this.paletteSearchAndUpdate();
    1176         }.bind(this), 750);
    1177       }
     1300      clearTimeout(this.debounceTimeout);
     1301      this.debounceTimeout = setTimeout(async function() {
     1302        this.debounceTimeout = null;
     1303        await this.paletteSearchAndUpdate();
     1304      }.bind(this), 750);
     1305    }
     1306    isKeyword(inputString) {
     1307      return Object.keys(globalThis.turboAdmin.searchModes).includes(inputString);
     1308    }
     1309    showPaletteNotice(text) {
     1310      this.paletteNoticeElement.classList.add("active");
     1311      this.paletteNoticeElement.innerText = text;
     1312    }
     1313    hidePaletteNotice() {
     1314      this.paletteNoticeElement.classList.remove("active");
    11781315    }
    11791316    async paletteActions(e) {
     
    11891326      }
    11901327      if (e.code === "Enter" && this.paletteShown()) {
     1328        e.preventDefault();
    11911329        this.doAction(this.metaPressed(e));
    11921330        return;
     
    11951333        return;
    11961334      }
     1335      this.maybeHighlightInputKeyword(e.key);
     1336      if (!this.inSearchMode() && (e.code === "Tab" || e.key === ":")) {
     1337        console.log("Checking for search mode");
     1338        let inputValue = this.paletteInputElement.value;
     1339        if (this.isKeyword(inputValue)) {
     1340          console.log("Found search mode " + inputValue);
     1341          e.preventDefault();
     1342          await this.enterSearchMode(globalThis.turboAdmin.searchModes[inputValue]);
     1343          return;
     1344        }
     1345      }
     1346      if (this.inSearchMode() && e.code === "Backspace" && this.paletteInputElement.value === "") {
     1347        e.preventDefault();
     1348        this.leaveSearchMode();
     1349        return;
     1350      }
    11971351      await this.debouncedPaletteSearchAndUpdate();
    11981352    }
     1353    async enterSearchMode(searchMode) {
     1354      console.log("Entering search mode for keyword " + searchMode.keyword);
     1355      this.backupPaletteData();
     1356      this.paletteData = [];
     1357      this.paletteItems = [];
     1358      this.itemIndex = [];
     1359      this.hidePaletteNotice();
     1360      this.searchMode = searchMode;
     1361      this.paletteInputElement.value = "";
     1362      this.addSearchModeTag(searchMode.displayName);
     1363      this.unhighlightInputKeyword();
     1364      this.updatePaletteItems();
     1365      if (searchMode.defaultItemsCallback !== null) {
     1366        this.paletteInnerElement.classList.add("loading");
     1367        const results = await searchMode.defaultItemsCallback();
     1368        this.setContentItems(results);
     1369        this.paletteInnerElement.classList.remove("loading");
     1370      }
     1371    }
     1372    leaveSearchMode() {
     1373      const searchMode = this.searchMode;
     1374      this.searchMode = null;
     1375      this.removeSearchModeTag();
     1376      this.restorePaletteData();
     1377      this.paletteInputElement.value = searchMode.keyword;
     1378      this.maybeHighlightInputKeyword("");
     1379      this.paletteSearchAndUpdate();
     1380    }
     1381    backupPaletteData() {
     1382      this.paletteDataBackup = this.paletteData;
     1383      this.paletteItemsBackup = this.paletteItems;
     1384      this.paletteItemIndexBackup = this.itemIndex;
     1385    }
     1386    restorePaletteData() {
     1387      this.paletteData = this.paletteDataBackup;
     1388      this.paletteItems = this.paletteItemsBackup;
     1389      this.itemIndex = this.paletteItemIndexBackup;
     1390    }
     1391    addSearchModeTag(title) {
     1392      this.paletteSearchModeTag.classList.add("active");
     1393      this.paletteSearchModeTag.innerText = title;
     1394    }
     1395    removeSearchModeTag() {
     1396      this.paletteSearchModeTag.classList.remove("active");
     1397    }
     1398    isPaletteOpen() {
     1399      return this.paletteElement?.classList.contains("active");
     1400    }
    11991401    showPalette() {
     1402      if (this.isPaletteOpen()) {
     1403        return;
     1404      }
    12001405      this.paletteInputElement.value = "";
    1201       this.paletteItemsElement.scrollTop = 0;
     1406      this.paletteInputElement?.focus();
    12021407      this.paletteElement?.classList.add("active");
    1203       this.paletteInputElement?.focus();
     1408      setTimeout(() => this.paletteItemsElement.scrollTop = 0, 100);
    12041409    }
    12051410    hidePalette() {
     
    12111416        this.closeSubMenu();
    12121417      }
     1418      if (this.searchMode !== null) {
     1419        this.leaveSearchMode();
     1420      }
    12131421    }
    12141422    paletteShown() {
     
    12341442    setSelectedElement() {
    12351443      if (this.isSubMenuOpen()) {
    1236         this.paletteItemsElement?.querySelectorAll(".ta-submenu.active li.selected")?.forEach((e) => e.classList.remove("selected"));
     1444        this.paletteSubmenuContainerElement?.querySelectorAll(".ta-submenu li.selected")?.forEach((e) => e.classList.remove("selected"));
    12371445        this.selectedSubItem.classList.add("selected");
    12381446      } else {
     
    13011509    }
    13021510    openSubMenu(subMenuElement) {
    1303       const subMenuHeight = subMenuElement.offsetHeight;
    1304       this.paletteItemsElement.style.minHeight = subMenuHeight + "px";
    1305       subMenuElement.classList.add("active");
     1511      this.paletteSubmenuContainerElement.replaceChildren(subMenuElement);
     1512      const subMenuHeight = this.paletteSubmenuContainerElement.offsetHeight;
     1513      this.paletteItemsContainerElement.style.minHeight = subMenuHeight + "px";
     1514      this.paletteSubmenuContainerElement.classList.add("active");
    13061515      this.selectedSubItem = subMenuElement.querySelector("li");
    13071516      this.openedSubMenu = subMenuElement;
     
    13141523        subMenuElement = document.querySelector(".ta-submenu.active");
    13151524      }
    1316       subMenuElement.classList.remove("active");
     1525      this.paletteSubmenuContainerElement.classList.remove("active");
    13171526      this.selectedSubItem.classList.remove("active");
    1318       this.paletteItemsElement.style.minHeight = "auto";
     1527      this.paletteItemsContainerElement.style.minHeight = "auto";
    13191528      this.selectedSubItem = null;
    13201529      this.openedSubMenu = null;
     
    13381547      const link = item.querySelector("a");
    13391548      const url = link.href;
     1549      if (link.getAttribute("href") === "") {
     1550        return;
     1551      }
    13401552      if (link.dataset.action === "clipboard") {
    13411553        navigator.clipboard.writeText(url);
     
    13561568    }
    13571569    async paletteSearch() {
    1358       this.buildPaletteItems();
    1359       if (this.paletteInputElement.value !== "") {
    1360         this.paletteFuse = new import_fuse_6_4_6.default(this.paletteItems, this.paletteFuseOptions);
    1361         this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map((i) => i.item);
    1362       }
    1363       if (globalThis.contentApi.active && this.postTypes !== [] && this.paletteInputElement.value.length > 2) {
     1570      if (!this.searchMode) {
     1571        this.buildPaletteItems();
     1572        if (this.paletteInputElement.value !== "") {
     1573          this.paletteFuse = new import_fuse_6_4_6.default(this.paletteItems, this.paletteFuseOptions);
     1574          this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map((i) => i.item);
     1575        }
     1576        return;
     1577      }
     1578      if (this.paletteInputElement.value.length === 0) {
    13641579        this.paletteInnerElement.classList.add("loading");
    1365         globalThis.contentApi.getPosts(this.paletteInputElement.value).then((results) => {
    1366           this.injectContentItems(results);
    1367           this.paletteInnerElement.classList.remove("loading");
    1368         });
     1580        let results = [];
     1581        if (this.searchMode.defaultItemsCallback !== null) {
     1582          results = await this.searchMode.defaultItemsCallback();
     1583        }
     1584        this.setContentItems(results);
     1585        this.paletteInnerElement.classList.remove("loading");
     1586      } else {
     1587        this.paletteInnerElement.classList.add("loading");
     1588        const results = await this.searchMode.searchCallback(this.paletteInputElement.value);
     1589        this.setContentItems(results);
     1590        this.paletteInnerElement.classList.remove("loading");
    13691591      }
    13701592    }
     
    13841606  var class_turbo_admin_palette_default = TurboAdminPalette;
    13851607
    1386   // src/class-turbo-admin-wp-block-editor-fullscreen-kill.js
    1387   var TurboAdminWpBlockEditorFullscreenKill = class {
    1388     constructor() {
    1389       const attrObserver = new MutationObserver((mutations) => {
    1390         mutations.forEach((mu) => {
    1391           if (mu.type !== "attributes" && mu.attributeName !== "class") {
    1392             return;
    1393           }
    1394           if (mu.target.classList.contains("is-fullscreen-mode")) {
    1395             this.killFullScreenEditor();
    1396           }
    1397         });
    1398       });
    1399       attrObserver.observe(document.body, {attributes: true});
    1400       this.killFullScreenEditor();
    1401     }
    1402     killFullScreenEditor() {
    1403       if (!document.body.classList.contains("is-fullscreen-mode")) {
    1404         return;
    1405       }
    1406       document.body.classList.remove("is-fullscreen-mode");
    1407       document.body.classList.add("turbo-admin-killed-fullscreen");
    1408       const newStyles = document.createElement("style");
    1409       newStyles.innerHTML = "body.turbo-admin-killed-fullscreen .edit-post-fullscreen-mode-close { display: none; }";
    1410       document.body.appendChild(newStyles);
    1411     }
     1608  // src/types/class-item-definition.js
     1609  var ItemDefinition = class {
     1610    detectType = "dom";
     1611    detectSelector = "";
     1612    detectSelectorNone = "";
     1613    itemTitleFunction = null;
     1614    itemUrlFunction = null;
     1615    noCache = false;
    14121616  };
    1413   var class_turbo_admin_wp_block_editor_fullscreen_kill_default = TurboAdminWpBlockEditorFullscreenKill;
     1617  var class_item_definition_default = ItemDefinition;
    14141618
    1415   // src/class-turbo-admin-wp-block-editor-welcome-guide-kill.js
    1416   var TurboAdminWpBlockEditorWelcomeGuideKill = class {
    1417     constructor() {
    1418       const attrObserver = new MutationObserver((mutations) => {
    1419         mutations.forEach((mu) => {
    1420           if (document.body.classList.contains("ta-killed-post-welcome-guide")) {
    1421             return;
    1422           }
    1423           if (mu.type !== "attributes" && mu.attributeName !== "class") {
    1424             return;
    1425           }
    1426           if (!mu.target.classList.contains("modal-open")) {
    1427             return;
    1428           }
    1429           const welcomeGuide = document.querySelector(".edit-post-welcome-guide");
    1430           if (welcomeGuide) {
    1431             this.killWelcomeGuide();
    1432           }
    1433         });
    1434       });
    1435       attrObserver.observe(document.body, {attributes: true});
    1436       this.killWelcomeGuide();
    1437     }
    1438     killWelcomeGuide() {
    1439       const welcomeGuide = document.querySelector(".edit-post-welcome-guide");
    1440       if (welcomeGuide) {
    1441         const closeButton = welcomeGuide.querySelector(".components-modal__header button");
    1442         if (closeButton) {
    1443           closeButton.click();
    1444           document.body.classList.add("ta-killed-post-welcome-guide");
    1445         }
    1446       }
     1619  // src/types/class-turbo-admin-plugin.js
     1620  var TurboAdminPlugin = class {
     1621    name = "";
     1622    searchModes = [];
     1623    activated = false;
     1624    constructor(pluginName) {
     1625      this.name = pluginName;
     1626      this.registerPlugin();
     1627    }
     1628    registerPlugin() {
     1629      console.log("Inside plugin - requested registration of " + this.name);
     1630      globalThis.turboAdmin.registerPlugin(this);
     1631    }
     1632    shouldActivate() {
     1633      return false;
     1634    }
     1635    activate() {
     1636      this.activated = true;
     1637      this.registerSearchModes();
     1638    }
     1639    registerSearchModes() {
     1640      this.searchModes.forEach(globalThis.turboAdmin.registerSearchMode);
     1641    }
     1642    getAdditionalItemDefinitions() {
     1643      return [];
     1644    }
     1645    saveSetting(key, value) {
    14471646    }
    14481647  };
    1449   var class_turbo_admin_wp_block_editor_welcome_guide_kill_default = TurboAdminWpBlockEditorWelcomeGuideKill;
     1648  var class_turbo_admin_plugin_default = TurboAdminPlugin;
    14501649
    14511650  // src/class-turbo-admin-wp-notices.js
     
    15471746      noticesPanelInner.id = "ta-notices-panel-inner";
    15481747      noticesToHide.forEach((notice) => {
    1549         notice.classList.add("inline");
    15501748        noticesPanelInner.append(notice);
    15511749      });
     
    17431941  var class_list_table_shortcuts_default = ListTableShortcuts;
    17441942
    1745   // src/class-turbo-admin-barkeeper.js
    1746   var TurboAdminBarkeeper = class {
    1747     constructor(barkeeperState) {
     1943  // src/plugins/class-turbo-admin-barkeeper.js
     1944  var TurboAdminBarkeeper = class extends class_turbo_admin_plugin_default {
     1945    constructor() {
     1946      super("Barkeeper");
     1947    }
     1948    shouldActivate() {
     1949      if (globalThis.turboAdmin.options["barkeeper"] !== true) {
     1950        return false;
     1951      }
    17481952      if (!document.getElementById("wpadminbar")) {
    1749         return;
    1750       }
     1953        return false;
     1954      }
     1955      return true;
     1956    }
     1957    activate() {
     1958      super.activate();
    17511959      this.exclusionIds = [
    17521960        "wp-admin-bar-menu-toggle",
     
    17551963        "wp-admin-bar-updates"
    17561964      ];
    1757       this.barkeeperState = barkeeperState;
     1965      this.barkeeperState = globalThis.turboAdmin.options["barkeeper-state"];
    17581966      this.root = document.getElementById("wp-admin-bar-root-default");
    17591967      this.itemsToHide = document.querySelectorAll("#wp-admin-bar-root-default > li");
     
    17731981        this.root.classList.toggle("ta-barkeeper-closed");
    17741982        this.barkeeperState = this.barkeeperState === "open" ? "closed" : "open";
    1775         if (typeof browser === "object") {
    1776           browser.runtime.sendMessage({
    1777             action: "barkeeperSetState",
    1778             barkeeperState: this.barkeeperState
    1779           });
    1780         } else {
    1781           window.localStorage.setItem("turboAdminBarkeeperState", this.barkeeperState);
    1782         }
     1983        browser.runtime.sendMessage({
     1984          action: "barkeeperSetState",
     1985          barkeeperState: this.barkeeperState
     1986        });
    17831987      });
    17841988      this.root.insertAdjacentElement("afterend", this.button);
     
    17861990  };
    17871991  var class_turbo_admin_barkeeper_default = TurboAdminBarkeeper;
     1992
     1993  // src/plugins/class-turbo-admin-content-search.js
     1994  var TurboAdminContentSearch = class extends class_turbo_admin_plugin_default {
     1995    constructor() {
     1996      super("WP Content");
     1997      const postTypeKeys = Object.keys(globalThis.contentApi.postTypes);
     1998      for (let i = 0; i < postTypeKeys.length; i++) {
     1999        const thisPostTypeKey = postTypeKeys[i];
     2000        const thisPostType = globalThis.contentApi.postTypes[thisPostTypeKey];
     2001        this.searchModes.push(this.makePostTypeSearchMode(thisPostType));
     2002      }
     2003      this.searchModes.push(new class_search_mode_default("id", "Post ID", this.postById.bind(this)));
     2004      this.searchModes.push(new class_search_mode_default("search", "All post types", this.contentSearch.bind(this)));
     2005      this.searchModes.push(new class_search_mode_default("find", "All post types", this.contentSearch.bind(this)));
     2006    }
     2007    shouldActivate() {
     2008      return true;
     2009    }
     2010    activate() {
     2011      super.activate();
     2012    }
     2013    makePostTypeSearchMode(postType) {
     2014      return new class_search_mode_default(postType.slug, postType.name, (searchString) => this.contentSearch(searchString, postType.slug));
     2015    }
     2016    async contentSearch(searchString, postType = "any") {
     2017      const results = await globalThis.contentApi.getPosts(searchString, postType);
     2018      if (!Array.isArray(results)) {
     2019        return [];
     2020      }
     2021      return results.map((result) => {
     2022        const item = new class_content_item_default();
     2023        item.title = result.title;
     2024        item.subtype = result.subtype;
     2025        item.url = result.url;
     2026        item.submenuItems = item.submenuItems.concat(this.makeSubmenuItems(result.id, item));
     2027        return item;
     2028      });
     2029    }
     2030    async postById(postId) {
     2031      if (!postId.trim().match(/^\d+$/)) {
     2032        return [];
     2033      }
     2034      const postExists = await globalThis.contentApi.doesPostExist(postId);
     2035      const resultAsContentItem = new class_content_item_default();
     2036      if (!postExists) {
     2037        resultAsContentItem.title = "Post does not exist or is not visible";
     2038        return [resultAsContentItem];
     2039      }
     2040      resultAsContentItem.title = `Post ID: ${postId}`;
     2041      resultAsContentItem.url = globalThis.taWp.home + `/?p=${postId}`;
     2042      resultAsContentItem.submenuItems = resultAsContentItem.submenuItems.concat(this.makeSubmenuItems(postId, resultAsContentItem));
     2043      return [resultAsContentItem];
     2044    }
     2045    makeSubmenuItems(postId, contentItem) {
     2046      const itemsToReturn = [];
     2047      itemsToReturn.push(new class_submenu_item_default("View", contentItem.url));
     2048      if (globalThis.turboAdmin.turboAdminPalette.profileLink) {
     2049        const editLink = globalThis.taWp.siteUrl + `/post.php?post=${postId}&action=edit`;
     2050        itemsToReturn.push(new class_submenu_item_default("Edit", editLink));
     2051        if (globalThis.turboAdmin.hasActivatedPlugin("OxygenBuilder")) {
     2052          const oxygenLink = globalThis.taWp.home + `?page_id=${postId}&ct_builder=true&ct_inner=true`;
     2053          itemsToReturn.push(new class_submenu_item_default("Edit with Oxygen", oxygenLink));
     2054        }
     2055      }
     2056      const copyLinkItem = new class_submenu_item_default("Copy link", contentItem.url);
     2057      copyLinkItem.addAttribute("data-action", "clipboard");
     2058      itemsToReturn.push(copyLinkItem);
     2059      return itemsToReturn;
     2060    }
     2061  };
     2062  var class_turbo_admin_content_search_default = TurboAdminContentSearch;
     2063
     2064  // src/plugins/class-turbo-admin-plugins.js
     2065  var TurboAdminPluginSearch = class extends class_turbo_admin_plugin_default {
     2066    constructor() {
     2067      super("WP Plugins");
     2068      this.searchModes.push(new class_search_mode_default("plugin", "Plugins", this.pluginSearch, this.defaultPluginItems.bind(this)));
     2069    }
     2070    shouldActivate() {
     2071      return true;
     2072    }
     2073    activate() {
     2074      super.activate();
     2075    }
     2076    async defaultPluginItems() {
     2077      return await this.pluginSearch("");
     2078    }
     2079    async pluginSearch(searchString) {
     2080      const results = await globalThis.contentApi.getPlugins(searchString);
     2081      if (!Array.isArray(results)) {
     2082        return [];
     2083      }
     2084      return results.map((result) => {
     2085        const item = new class_content_item_default();
     2086        item.title = result.name;
     2087        item.subtype = "Plugin";
     2088        const itemViewUrlParams = new URLSearchParams();
     2089        itemViewUrlParams.set("plugin_status", "all");
     2090        itemViewUrlParams.set("s", result.name);
     2091        item.submenuItems.push(new class_submenu_item_default("View", globalThis.taWp.siteUrl + "/plugins.php?" + itemViewUrlParams.toString()));
     2092        return item;
     2093      });
     2094    }
     2095  };
     2096  var class_turbo_admin_plugins_default = TurboAdminPluginSearch;
     2097
     2098  // src/plugins/class-turbo-admin-users.js
     2099  var TurboAdminUserSearch = class extends class_turbo_admin_plugin_default {
     2100    constructor() {
     2101      super("WP Users");
     2102      this.searchModes.push(new class_search_mode_default("user", "Users", this.userSearch, this.defaultUserItems.bind(this)));
     2103    }
     2104    shouldActivate() {
     2105      return true;
     2106    }
     2107    activate() {
     2108      super.activate();
     2109    }
     2110    async defaultUserItems() {
     2111      return await this.userSearch("");
     2112    }
     2113    async userSearch(searchString) {
     2114      const results = await globalThis.contentApi.getUsers(searchString);
     2115      if (!Array.isArray(results)) {
     2116        return [];
     2117      }
     2118      return results.map((result) => {
     2119        const item = new class_content_item_default();
     2120        if (result.first_name && result.last_name) {
     2121          item.title = `${result.first_name} ${result.last_name} - `;
     2122        }
     2123        item.title += result.email;
     2124        item.subtype = result.roles[0];
     2125        item.url = globalThis.taWp.siteUrl + `/user-edit.php?user_id=${result.id}`;
     2126        return item;
     2127      });
     2128    }
     2129  };
     2130  var class_turbo_admin_users_default = TurboAdminUserSearch;
     2131
     2132  // src/plugins/class-turbo-admin-mu-sites.js
     2133  var TurboAdminMUSites = class extends class_turbo_admin_plugin_default {
     2134    constructor() {
     2135      super("WP Multisite Sites");
     2136      this.searchModes.push(new class_search_mode_default("site", "Sites", this.siteSearch.bind(this), this.defaultSiteItems.bind(this)));
     2137    }
     2138    shouldActivate() {
     2139      return Boolean(document.querySelector("#wp-admin-bar-my-sites"));
     2140    }
     2141    activate() {
     2142      super.activate();
     2143    }
     2144    async defaultSiteItems() {
     2145      return await this.siteSearch("");
     2146    }
     2147    async siteSearch(searchString) {
     2148      const sites = document.querySelectorAll("#wp-admin-bar-my-sites #wp-admin-bar-my-sites-list > li");
     2149      if (sites.length === 0) {
     2150        return [];
     2151      }
     2152      const sitesArray = Array.from(sites);
     2153      const sitesLinks = sitesArray.map((site) => site.querySelector("a"));
     2154      const filteredSites = sitesLinks.filter((site) => site.innerText.toLowerCase().includes(searchString.toLowerCase()));
     2155      return filteredSites.map((site) => {
     2156        const item = new class_content_item_default();
     2157        item.title = site.innerText;
     2158        item.subtype = "Site";
     2159        item.url = site.href;
     2160        item.submenuItems = item.submenuItems.concat(this.makeSubmenuItems(site));
     2161        return item;
     2162      });
     2163    }
     2164    makeSubmenuItems(siteElement) {
     2165      const submenuItems = [];
     2166      const submenu = siteElement.nextElementSibling.querySelector(`.ab-submenu`);
     2167      if (!submenu) {
     2168        return [];
     2169      }
     2170      const submenuLinks = submenu.querySelectorAll("a");
     2171      if (submenuLinks.length === 0) {
     2172        return [];
     2173      }
     2174      const submenuLinksArray = Array.from(submenuLinks);
     2175      submenuLinksArray.forEach((link) => {
     2176        const submenuItem = new class_submenu_item_default(link.innerText, link.href);
     2177        submenuItems.push(submenuItem);
     2178      });
     2179      return submenuItems;
     2180    }
     2181  };
     2182  var class_turbo_admin_mu_sites_default = TurboAdminMUSites;
     2183
     2184  // src/plugins/class-turbo-admin-oxygen-buillder.js
     2185  var TurboAdminOxygenBuilder = class extends class_turbo_admin_plugin_default {
     2186    constructor() {
     2187      super("OxygenBuilder");
     2188    }
     2189    shouldActivate() {
     2190      let oxygenLinkElem = document.getElementById("toplevel_page_ct_dashboard_page");
     2191      if (!oxygenLinkElem) {
     2192        oxygenLinkElem = document.getElementById("wp-admin-bar-oxygen_admin_bar_menu");
     2193      }
     2194      if (!oxygenLinkElem) {
     2195        oxygenLinkElem = Number(window.localStorage.getItem("ta-has-oxygen-builder"));
     2196      }
     2197      const hasOxygenBuilder = Boolean(oxygenLinkElem);
     2198      window.localStorage.setItem("ta-has-oxygen-builder", hasOxygenBuilder ? "1" : "0");
     2199      return hasOxygenBuilder;
     2200    }
     2201    activate() {
     2202      super.activate();
     2203    }
     2204    getAdditionalItemDefinitions() {
     2205      const editDefinition = new class_item_definition_default();
     2206      editDefinition.detectType = "dom";
     2207      editDefinition.detectSelector = "#ct-edit-template-builder";
     2208      editDefinition.itemTitleFunction = () => "Edit with Oxygen";
     2209      editDefinition.itemUrlFunction = (element) => element.href;
     2210      editDefinition.noCache = true;
     2211      const backToWpDefinition = new class_item_definition_default();
     2212      backToWpDefinition.detectType = "dom";
     2213      backToWpDefinition.detectSelector = ".oxygen-back-to-wp-menu .oxygen-toolbar-button-dropdown a:not(:last-of-type)";
     2214      backToWpDefinition.itemTitleFunction = (element) => "Back to WP: " + element.textContent;
     2215      backToWpDefinition.itemUrlFunction = (element) => {
     2216        if (element.href) {
     2217          return element.href;
     2218        } else {
     2219          let url = new URL(window.location.href);
     2220          return url.origin + url.pathname;
     2221        }
     2222      };
     2223      backToWpDefinition.noCache = true;
     2224      return [
     2225        editDefinition,
     2226        backToWpDefinition
     2227      ];
     2228    }
     2229  };
     2230  var class_turbo_admin_oxygen_buillder_default = TurboAdminOxygenBuilder;
    17882231
    17892232  // src/class-turbo-admin.js
    17902233  var TurboAdmin = class {
    17912234    constructor(options) {
     2235      this.doInit = true;
    17922236      if (document.getElementById("ta-command-palette-container")) {
    17932237        console.log("TurboAdmin already initialised - I won't make a second copy!");
     2238        this.doInit = false;
     2239        return globalThis.turboAdmin;
     2240      }
     2241      this.options = options;
     2242      this.plugins = {};
     2243      this.searchModes = {};
     2244      this.menuNeedsRefresh = false;
     2245    }
     2246    async init() {
     2247      if (!this.doInit) {
    17942248        return;
    17952249      }
    1796       this.options = options;
    1797     }
    1798     async init() {
     2250      new class_turbo_admin_barkeeper_default();
     2251      new class_turbo_admin_content_search_default();
     2252      new class_turbo_admin_plugins_default();
     2253      new class_turbo_admin_users_default();
     2254      new class_turbo_admin_mu_sites_default();
     2255      new class_turbo_admin_oxygen_buillder_default();
    17992256      this.wp = globalThis.taWp;
    18002257      this.menu = [];
    18012258      if (!this.wp.isBackend) {
    18022259        if (!this.wp.siteChanged) {
    1803           const savedMenu = window.localStorage.getItem("ta-palette-data");
    1804           if (savedMenu !== null) {
    1805             if (document.body.classList.contains("logged-in")) {
     2260          if (document.body.classList.contains("logged-in")) {
     2261            const savedMenu = window.localStorage.getItem("ta-palette-data");
     2262            if (savedMenu === null) {
     2263              this.menuNeedsRefresh = true;
     2264            } else {
    18062265              this.menu = JSON.parse(savedMenu);
     2266              if (!this.menu.some((item) => item.action.endsWith("upload.php"))) {
     2267                this.menuNeedsRefresh = true;
     2268              }
    18072269            }
    18082270          }
     
    18182280      this.addPalette();
    18192281      this.turboAdminPalette = new class_turbo_admin_palette_default(this.menu, this.options);
    1820       if (this.options["block-editor-fullscreen-disable"] === true) {
    1821         this.turboAdminFullscreenKill = new class_turbo_admin_wp_block_editor_fullscreen_kill_default();
    1822       }
    1823       if (this.options["block-editor-welcome-screen-kill"] === true) {
    1824         this.turboAdminWelcomeKill = new class_turbo_admin_wp_block_editor_welcome_guide_kill_default();
    1825       }
     2282    }
     2283    activatePlugins() {
     2284      Object.keys(this.plugins).forEach((plugin) => {
     2285        if (this.plugins[plugin].shouldActivate()) {
     2286          this.plugins[plugin].activate();
     2287        }
     2288      });
    18262289      if (this.options["list-table-keyboard-shortcuts"] === true) {
    18272290        this.turboAdminListTableShortcuts = new class_list_table_shortcuts_default();
    18282291      }
    1829       if (this.options["barkeeper"] === true) {
    1830         if (typeof browser !== "object") {
    1831           this.options["barkeeper-state"] = window.localStorage.getItem("turboAdminBarkeeperState");
    1832         }
    1833         this.turboAdminBarkeeper = new class_turbo_admin_barkeeper_default(this.options["barkeeper-state"]);
    1834       }
    18352292      if (globalThis.contentApi.userLoggedIn()) {
    18362293      }
     2294    }
     2295    hasActivatedPlugin(name) {
     2296      return Object.keys(this.plugins).includes(name) && this.plugins[name].activated;
    18372297    }
    18382298    getMenu() {
     
    18692329    addAdditionalMenuItems() {
    18702330      let extraItems = this.options.extraItems ?? [];
     2331      const pluginKeys = Object.keys(this.plugins);
     2332      for (let i = 0; i < pluginKeys.length; i++) {
     2333        extraItems = extraItems.concat(this.plugins[pluginKeys[i]].getAdditionalItemDefinitions());
     2334      }
    18712335      extraItems = extraItems.concat([
    18722336        {
     
    19422406          itemTitleFunction: (element) => "Network Admin: " + element.textContent,
    19432407          itemUrlFunction: (element) => element.href
    1944         },
    1945         {
    1946           detectType: "dom",
    1947           detectSelector: "#wp-admin-bar-my-sites #wp-admin-bar-my-sites-list .ab-submenu a",
    1948           itemTitleFunction: (element) => "Sites: " + element.closest(".menupop").querySelector("a").innerText + " - " + element.innerText,
    1949           itemUrlFunction: (element) => element.href
    1950         },
    1951         {
    1952           detectType: "dom",
    1953           detectSelector: "#ct-edit-template-builder",
    1954           itemTitleFunction: () => "Edit with Oxygen",
    1955           itemUrlFunction: (element) => element.href,
    1956           noCache: true
    1957         },
    1958         {
    1959           detectType: "dom",
    1960           detectSelector: ".oxygen-back-to-wp-menu .oxygen-toolbar-button-dropdown a:not(:last-of-type)",
    1961           itemTitleFunction: (element) => "Back to WP: " + element.textContent,
    1962           itemUrlFunction: (element) => {
    1963             if (element.href) {
    1964               return element.href;
    1965             } else {
    1966               let url = new URL(window.location.href);
    1967               return url.origin + url.pathname;
    1968             }
    1969           },
    1970           noCache: true
    19712408        }
    19722409      ]);
     
    20052442      const palette = document.createElement("div");
    20062443      palette.id = "ta-command-palette";
     2444      const paletteNotice = document.createElement("div");
     2445      paletteNotice.id = "ta-command-palette-notice";
     2446      const tabNotice = document.createElement("div");
     2447      tabNotice.id = "ta-command-palette-tab-notice";
     2448      const tabNoticeText = document.createElement("span");
     2449      tabNoticeText.id = "ta-command-palette-tab-notice-text";
     2450      const tabNoticeButton = document.createElement("span");
     2451      tabNoticeButton.id = "ta-command-palette-tab-notice-button";
     2452      tabNoticeButton.innerText = "Tab";
    20072453      const input = document.createElement("input");
    20082454      input.id = "ta-command-palette-input";
     
    20102456      input.type = "text";
    20112457      input.setAttribute("autocomplete", "off");
     2458      const searchModeTag = document.createElement("div");
     2459      searchModeTag.id = "ta-command-palette-search-mode-tag";
     2460      const listContainer = document.createElement("div");
     2461      listContainer.id = "ta-command-palette-items-container";
    20122462      const list = document.createElement("ul");
    20132463      list.id = "ta-command-palette-items";
     2464      const submenuContainer = document.createElement("div");
     2465      submenuContainer.id = "ta-command-palette-submenu-container";
    20142466      container.appendChild(palette);
     2467      palette.appendChild(searchModeTag);
     2468      palette.appendChild(paletteNotice);
     2469      tabNotice.appendChild(tabNoticeText);
     2470      tabNotice.appendChild(tabNoticeButton);
     2471      palette.appendChild(tabNotice);
    20152472      palette.appendChild(input);
    2016       palette.appendChild(list);
     2473      listContainer.appendChild(list);
     2474      listContainer.appendChild(submenuContainer);
     2475      palette.appendChild(listContainer);
    20172476      if (document.getElementById("wpadminbar") && this.options["admin-bar-search"] === true) {
    20182477        const paletteLi = document.createElement("li");
     
    20252484        placeholder.innerText = this.buildShortcutKeysString();
    20262485        placeholder.addEventListener("click", (e) => input.focus());
    2027         palette.insertBefore(placeholder, list);
     2486        palette.insertBefore(placeholder, listContainer);
    20282487      } else {
    20292488        document.querySelector(this.options.appendToElement ?? "body").appendChild(container);
    20302489      }
     2490    }
     2491    registerPlugin(plugin) {
     2492      console.log("Registering plugin " + plugin.name);
     2493      this.plugins[plugin.name] = plugin;
     2494    }
     2495    registerSearchMode(searchMode) {
     2496      console.log("Registering search mode with keyword " + searchMode.keyword);
     2497      globalThis.turboAdmin.searchModes[searchMode.keyword] = searchMode;
    20312498    }
    20322499    buildShortcutKeysString() {
     
    20452512        keysString += "Shift-";
    20462513      }
    2047       keysString += shortcut.key.toUpperCase();
     2514      keysString += shortcut.key;
    20482515      return keysString;
    20492516    }
     
    21732640  var class_wp_default = Wp;
    21742641
     2642  // src/apis/class-woocommerce-api.js
     2643  var WoocommerceApi = class {
     2644    constructor() {
     2645      this.cache = {};
     2646    }
     2647    async getOrders(searchString) {
     2648      if (this.cache["orders-" + searchString] !== void 0) {
     2649        return this.cache["orders-" + searchString];
     2650      }
     2651      const response = await this.wooGet("orders", {
     2652        search: searchString,
     2653        per_page: 100
     2654      });
     2655      if (response === false) {
     2656        return false;
     2657      }
     2658      const result = await response.json();
     2659      this.cache["orders-" + searchString] = result;
     2660      return result;
     2661    }
     2662    async getOrder(orderId) {
     2663      if (this.cache["order-" + orderId] !== void 0) {
     2664        return this.cache["order-" + orderId];
     2665      }
     2666      const response = await this.wooGet(`orders/${orderId}`);
     2667      if (response === false) {
     2668        return false;
     2669      }
     2670      const result = await response.json();
     2671      let resultAsArray = [result];
     2672      this.cache["order-" + orderId] = resultAsArray;
     2673      return resultAsArray;
     2674    }
     2675    async getCustomers(searchString) {
     2676      if (this.cache["customers-" + searchString] !== void 0) {
     2677        return this.cache["customers-" + searchString];
     2678      }
     2679      const response = await this.wooGet("customers", {
     2680        search: searchString,
     2681        per_page: 100,
     2682        role: "all"
     2683      });
     2684      if (response === false) {
     2685        return false;
     2686      }
     2687      const result = await response.json();
     2688      this.cache["customers-" + searchString] = result;
     2689      return result;
     2690    }
     2691    async wooGet(path, data = {}) {
     2692      const wooApiBase = globalThis.contentApi.apiRoot + "wc/v3/";
     2693      const init = {
     2694        method: "GET",
     2695        headers: {},
     2696        mode: "cors",
     2697        cache: "no-store",
     2698        credentials: "include"
     2699      };
     2700      if (globalThis.contentApi.apiNonce) {
     2701        data._wpnonce = globalThis.contentApi.apiNonce;
     2702      }
     2703      const params = globalThis.contentApi.makeParamString(data);
     2704      const response = await fetch(`${wooApiBase}${path}/?${params}`, init);
     2705      if (response.status === 404) {
     2706        return false;
     2707      }
     2708      if (response.status < 200 || response.status >= 300) {
     2709        globalThis.turboAdmin.turboAdminPalette.showPaletteNotice("WooCommerce API Error. Try visiting the dashboard to refresh things.");
     2710      }
     2711      return response;
     2712    }
     2713  };
     2714  var class_woocommerce_api_default = WoocommerceApi;
     2715
     2716  // src/apis/class-gravity-forms-api.js
     2717  var GravityFormsApi = class {
     2718    constructor() {
     2719      this.cache = {};
     2720    }
     2721    async getForms(searchString) {
     2722      if (this.cache["gf-forms-" + searchString] !== void 0) {
     2723        return this.cache["gf-forms-" + searchString];
     2724      }
     2725      const response = await this.gfGet("forms", {});
     2726      const result = await response.json();
     2727      const searchStringLowerCase = searchString.toLowerCase();
     2728      const formIds = Object.keys(result);
     2729      for (let k = 0; k < formIds.length; k++) {
     2730        const thisId = formIds[k];
     2731        if (!result[thisId].title.toLowerCase().includes(searchStringLowerCase)) {
     2732          delete result[thisId];
     2733        }
     2734      }
     2735      this.cache["gf-forms-" + searchString] = result;
     2736      return result;
     2737    }
     2738    async gfGet(path, data = {}) {
     2739      const gfApiBase = globalThis.contentApi.apiRoot + "gf/v2/";
     2740      const init = {
     2741        method: "GET",
     2742        headers: {},
     2743        mode: "cors",
     2744        cache: "no-store",
     2745        credentials: "include"
     2746      };
     2747      if (globalThis.contentApi.apiNonce) {
     2748        data._wpnonce = globalThis.contentApi.apiNonce;
     2749      }
     2750      const params = globalThis.contentApi.makeParamString(data);
     2751      const response = await fetch(`${gfApiBase}${path}/?${params}`);
     2752      if (response.status < 200 || response.status >= 300) {
     2753        globalThis.turboAdmin.turboAdminPalette.showPaletteNotice("Gravity Forms API Error. Try visiting the dashboard to refresh things.");
     2754      }
     2755      return response;
     2756    }
     2757  };
     2758  var class_gravity_forms_api_default = GravityFormsApi;
     2759
    21752760  // src/main.js
    21762761  var taStorageKey = "turbo-admin-settings";
    21772762  async function taInit(settings) {
     2763    if (typeof globalThis.turboAdmin !== "undefined") {
     2764      return;
     2765    }
    21782766    globalThis.turboAdmin = null;
    21792767    if (typeof settings[taStorageKey] === "undefined") {
     
    21822770    }
    21832771    globalThis.turboAdminOptions = settings[taStorageKey];
     2772    console.log("Preparing Turbo Admin");
    21842773    globalThis.taWp = new class_wp_default();
    21852774    await globalThis.taWp.completeInit();
     
    21872776    globalThis.contentApi = new class_content_api_default();
    21882777    await globalThis.contentApi.discoverApiRoot();
     2778    await globalThis.contentApi.discoverPostTypes();
     2779    globalThis.woocommerceApi = new class_woocommerce_api_default();
     2780    globalThis.gravityFormsApi = new class_gravity_forms_api_default();
    21892781    console.log("Turbo Admin: Content API is initialised");
    21902782    globalThis.turboAdmin = new class_turbo_admin_default(globalThis.turboAdminOptions);
    21912783    await globalThis.turboAdmin.init();
     2784    await globalThis.turboAdmin.activatePlugins();
    21922785    if (settings[taStorageKey]["hide-notices"]) {
    21932786      globalThis.turboAdminWpNotices = new class_turbo_admin_wp_notices_default(settings[taStorageKey].rememberedNoticeIds);
  • turbo-admin/trunk/dist/main.min.js.map

    r2703739 r2835882  
    11{
    22  "version": 3,
    3   "sources": ["../src/fuse-6.4.6.js", "../src/class-turbo-admin-palette.js", "../src/class-turbo-admin-menu-item.js", "../src/class-storage.js", "../src/class-content-api.js", "../src/class-turbo-admin-wp-block-editor-fullscreen-kill.js", "../src/class-turbo-admin-wp-block-editor-welcome-guide-kill.js", "../src/class-turbo-admin-wp-notices.js", "../src/class-list-table-shortcuts.js", "../src/class-turbo-admin-barkeeper.js", "../src/class-turbo-admin.js", "../src/class-wp.js", "../src/main.js"],
    4   "sourcesContent": ["/**\n * Fuse.js v6.4.6 - Lightweight fuzzy-search (http://fusejs.io)\n *\n * Copyright (c) 2021 Kiro Risk (http://kiro.me)\n * All Rights Reserved. Apache Software License 2.0\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\nvar e, t; e = this, t = function () { \"use strict\"; function e(t) { return (e = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (e) { return typeof e } : function (e) { return e && \"function\" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? \"symbol\" : typeof e })(t) } function t(e, t) { if (!(e instanceof t)) throw new TypeError(\"Cannot call a class as a function\") } function n(e, t) { for (var n = 0; n < t.length; n++) { var r = t[n]; r.enumerable = r.enumerable || !1, r.configurable = !0, \"value\" in r && (r.writable = !0), Object.defineProperty(e, r.key, r) } } function r(e, t, r) { return t && n(e.prototype, t), r && n(e, r), e } function i(e, t, n) { return t in e ? Object.defineProperty(e, t, { value: n, enumerable: !0, configurable: !0, writable: !0 }) : e[t] = n, e } function o(e, t) { var n = Object.keys(e); if (Object.getOwnPropertySymbols) { var r = Object.getOwnPropertySymbols(e); t && (r = r.filter((function (t) { return Object.getOwnPropertyDescriptor(e, t).enumerable }))), n.push.apply(n, r) } return n } function c(e) { for (var t = 1; t < arguments.length; t++) { var n = null != arguments[t] ? arguments[t] : {}; t % 2 ? o(Object(n), !0).forEach((function (t) { i(e, t, n[t]) })) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(n)) : o(Object(n)).forEach((function (t) { Object.defineProperty(e, t, Object.getOwnPropertyDescriptor(n, t)) })) } return e } function a(e, t) { if (\"function\" != typeof t && null !== t) throw new TypeError(\"Super expression must either be null or a function\"); e.prototype = Object.create(t && t.prototype, { constructor: { value: e, writable: !0, configurable: !0 } }), t && u(e, t) } function s(e) { return (s = Object.setPrototypeOf ? Object.getPrototypeOf : function (e) { return e.__proto__ || Object.getPrototypeOf(e) })(e) } function u(e, t) { return (u = Object.setPrototypeOf || function (e, t) { return e.__proto__ = t, e })(e, t) } function h(e, t) { return !t || \"object\" != typeof t && \"function\" != typeof t ? function (e) { if (void 0 === e) throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); return e }(e) : t } function f(e) { var t = function () { if (\"undefined\" == typeof Reflect || !Reflect.construct) return !1; if (Reflect.construct.sham) return !1; if (\"function\" == typeof Proxy) return !0; try { return Date.prototype.toString.call(Reflect.construct(Date, [], (function () { }))), !0 } catch (e) { return !1 } }(); return function () { var n, r = s(e); if (t) { var i = s(this).constructor; n = Reflect.construct(r, arguments, i) } else n = r.apply(this, arguments); return h(this, n) } } function l(e) { return function (e) { if (Array.isArray(e)) return d(e) }(e) || function (e) { if (\"undefined\" != typeof Symbol && Symbol.iterator in Object(e)) return Array.from(e) }(e) || function (e, t) { if (e) { if (\"string\" == typeof e) return d(e, t); var n = Object.prototype.toString.call(e).slice(8, -1); return \"Object\" === n && e.constructor && (n = e.constructor.name), \"Map\" === n || \"Set\" === n ? Array.from(e) : \"Arguments\" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n) ? d(e, t) : void 0 } }(e) || function () { throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\") }() } function d(e, t) { (null == t || t > e.length) && (t = e.length); for (var n = 0, r = new Array(t); n < t; n++)r[n] = e[n]; return r } function v(e) { return Array.isArray ? Array.isArray(e) : \"[object Array]\" === b(e) } function g(e) { return \"string\" == typeof e } function y(e) { return \"number\" == typeof e } function p(e) { return !0 === e || !1 === e || function (e) { return m(e) && null !== e }(e) && \"[object Boolean]\" == b(e) } function m(t) { return \"object\" === e(t) } function k(e) { return null != e } function M(e) { return !e.trim().length } function b(e) { return null == e ? void 0 === e ? \"[object Undefined]\" : \"[object Null]\" : Object.prototype.toString.call(e) } var x = function (e) { return \"Invalid value for key \".concat(e) }, L = function (e) { return \"Pattern length exceeds max of \".concat(e, \".\") }, S = Object.prototype.hasOwnProperty, w = function () { function e(n) { var r = this; t(this, e), this._keys = [], this._keyMap = {}; var i = 0; n.forEach((function (e) { var t = _(e); i += t.weight, r._keys.push(t), r._keyMap[t.id] = t, i += t.weight })), this._keys.forEach((function (e) { e.weight /= i })) } return r(e, [{ key: \"get\", value: function (e) { return this._keyMap[e] } }, { key: \"keys\", value: function () { return this._keys } }, { key: \"toJSON\", value: function () { return JSON.stringify(this._keys) } }]), e }(); function _(e) { var t = null, n = null, r = null, i = 1; if (g(e) || v(e)) r = e, t = O(e), n = j(e); else { if (!S.call(e, \"name\")) throw new Error(function (e) { return \"Missing \".concat(e, \" property in key\") }(\"name\")); var o = e.name; if (r = o, S.call(e, \"weight\") && (i = e.weight) <= 0) throw new Error(function (e) { return \"Property 'weight' in key '\".concat(e, \"' must be a positive integer\") }(o)); t = O(o), n = j(o) } return { path: t, id: n, weight: i, src: r } } function O(e) { return v(e) ? e : e.split(\".\") } function j(e) { return v(e) ? e.join(\".\") : e } var A = c({}, { isCaseSensitive: !1, includeScore: !1, keys: [], shouldSort: !0, sortFn: function (e, t) { return e.score === t.score ? e.idx < t.idx ? -1 : 1 : e.score < t.score ? -1 : 1 } }, {}, { includeMatches: !1, findAllMatches: !1, minMatchCharLength: 1 }, {}, { location: 0, threshold: .6, distance: 100 }, {}, { useExtendedSearch: !1, getFn: function (e, t) { var n = [], r = !1; return function e(t, i, o) { if (k(t)) if (i[o]) { var c = t[i[o]]; if (!k(c)) return; if (o === i.length - 1 && (g(c) || y(c) || p(c))) n.push(function (e) { return null == e ? \"\" : function (e) { if (\"string\" == typeof e) return e; var t = e + \"\"; return \"0\" == t && 1 / e == -1 / 0 ? \"-0\" : t }(e) }(c)); else if (v(c)) { r = !0; for (var a = 0, s = c.length; a < s; a += 1)e(c[a], i, o + 1) } else i.length && e(c, i, o + 1) } else n.push(t) }(e, g(t) ? t.split(\".\") : t, 0), r ? n : n[0] }, ignoreLocation: !1, ignoreFieldNorm: !1 }), I = /[^ ]+/g; function C() { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : 3, t = new Map, n = Math.pow(10, e); return { get: function (e) { var r = e.match(I).length; if (t.has(r)) return t.get(r); var i = 1 / Math.sqrt(r), o = parseFloat(Math.round(i * n) / n); return t.set(r, o), o }, clear: function () { t.clear() } } } var E = function () { function e() { var n = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}, r = n.getFn, i = void 0 === r ? A.getFn : r; t(this, e), this.norm = C(3), this.getFn = i, this.isCreated = !1, this.setIndexRecords() } return r(e, [{ key: \"setSources\", value: function () { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : []; this.docs = e } }, { key: \"setIndexRecords\", value: function () { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : []; this.records = e } }, { key: \"setKeys\", value: function () { var e = this, t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : []; this.keys = t, this._keysMap = {}, t.forEach((function (t, n) { e._keysMap[t.id] = n })) } }, { key: \"create\", value: function () { var e = this; !this.isCreated && this.docs.length && (this.isCreated = !0, g(this.docs[0]) ? this.docs.forEach((function (t, n) { e._addString(t, n) })) : this.docs.forEach((function (t, n) { e._addObject(t, n) })), this.norm.clear()) } }, { key: \"add\", value: function (e) { var t = this.size(); g(e) ? this._addString(e, t) : this._addObject(e, t) } }, { key: \"removeAt\", value: function (e) { this.records.splice(e, 1); for (var t = e, n = this.size(); t < n; t += 1)this.records[t].i -= 1 } }, { key: \"getValueForItemAtKeyId\", value: function (e, t) { return e[this._keysMap[t]] } }, { key: \"size\", value: function () { return this.records.length } }, { key: \"_addString\", value: function (e, t) { if (k(e) && !M(e)) { var n = { v: e, i: t, n: this.norm.get(e) }; this.records.push(n) } } }, { key: \"_addObject\", value: function (e, t) { var n = this, r = { i: t, $: {} }; this.keys.forEach((function (t, i) { var o = n.getFn(e, t.path); if (k(o)) if (v(o)) !function () { for (var e = [], t = [{ nestedArrIndex: -1, value: o }]; t.length;) { var c = t.pop(), a = c.nestedArrIndex, s = c.value; if (k(s)) if (g(s) && !M(s)) { var u = { v: s, i: a, n: n.norm.get(s) }; e.push(u) } else v(s) && s.forEach((function (e, n) { t.push({ nestedArrIndex: n, value: e }) })) } r.$[i] = e }(); else if (!M(o)) { var c = { v: o, n: n.norm.get(o) }; r.$[i] = c } })), this.records.push(r) } }, { key: \"toJSON\", value: function () { return { keys: this.keys, records: this.records } } }]), e }(); function $(e, t) { var n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, r = n.getFn, i = void 0 === r ? A.getFn : r, o = new E({ getFn: i }); return o.setKeys(e.map(_)), o.setSources(t), o.create(), o } function R(e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.errors, r = void 0 === n ? 0 : n, i = t.currentLocation, o = void 0 === i ? 0 : i, c = t.expectedLocation, a = void 0 === c ? 0 : c, s = t.distance, u = void 0 === s ? A.distance : s, h = t.ignoreLocation, f = void 0 === h ? A.ignoreLocation : h, l = r / e.length; if (f) return l; var d = Math.abs(a - o); return u ? l + d / u : d ? 1 : l } function F() { for (var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : [], t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : A.minMatchCharLength, n = [], r = -1, i = -1, o = 0, c = e.length; o < c; o += 1) { var a = e[o]; a && -1 === r ? r = o : a || -1 === r || ((i = o - 1) - r + 1 >= t && n.push([r, i]), r = -1) } return e[o - 1] && o - r >= t && n.push([r, o - 1]), n } function P(e) { for (var t = {}, n = 0, r = e.length; n < r; n += 1) { var i = e.charAt(n); t[i] = (t[i] || 0) | 1 << r - n - 1 } return t } var N = function () { function e(n) { var r = this, i = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, o = i.location, c = void 0 === o ? A.location : o, a = i.threshold, s = void 0 === a ? A.threshold : a, u = i.distance, h = void 0 === u ? A.distance : u, f = i.includeMatches, l = void 0 === f ? A.includeMatches : f, d = i.findAllMatches, v = void 0 === d ? A.findAllMatches : d, g = i.minMatchCharLength, y = void 0 === g ? A.minMatchCharLength : g, p = i.isCaseSensitive, m = void 0 === p ? A.isCaseSensitive : p, k = i.ignoreLocation, M = void 0 === k ? A.ignoreLocation : k; if (t(this, e), this.options = { location: c, threshold: s, distance: h, includeMatches: l, findAllMatches: v, minMatchCharLength: y, isCaseSensitive: m, ignoreLocation: M }, this.pattern = m ? n : n.toLowerCase(), this.chunks = [], this.pattern.length) { var b = function (e, t) { r.chunks.push({ pattern: e, alphabet: P(e), startIndex: t }) }, x = this.pattern.length; if (x > 32) { for (var L = 0, S = x % 32, w = x - S; L < w;)b(this.pattern.substr(L, 32), L), L += 32; if (S) { var _ = x - 32; b(this.pattern.substr(_), _) } } else b(this.pattern, 0) } } return r(e, [{ key: \"searchIn\", value: function (e) { var t = this.options, n = t.isCaseSensitive, r = t.includeMatches; if (n || (e = e.toLowerCase()), this.pattern === e) { var i = { isMatch: !0, score: 0 }; return r && (i.indices = [[0, e.length - 1]]), i } var o = this.options, c = o.location, a = o.distance, s = o.threshold, u = o.findAllMatches, h = o.minMatchCharLength, f = o.ignoreLocation, d = [], v = 0, g = !1; this.chunks.forEach((function (t) { var n = t.pattern, i = t.alphabet, o = t.startIndex, y = function (e, t, n) { var r = arguments.length > 3 && void 0 !== arguments[3] ? arguments[3] : {}, i = r.location, o = void 0 === i ? A.location : i, c = r.distance, a = void 0 === c ? A.distance : c, s = r.threshold, u = void 0 === s ? A.threshold : s, h = r.findAllMatches, f = void 0 === h ? A.findAllMatches : h, l = r.minMatchCharLength, d = void 0 === l ? A.minMatchCharLength : l, v = r.includeMatches, g = void 0 === v ? A.includeMatches : v, y = r.ignoreLocation, p = void 0 === y ? A.ignoreLocation : y; if (t.length > 32) throw new Error(L(32)); for (var m, k = t.length, M = e.length, b = Math.max(0, Math.min(o, M)), x = u, S = b, w = d > 1 || g, _ = w ? Array(M) : []; (m = e.indexOf(t, S)) > -1;) { var O = R(t, { currentLocation: m, expectedLocation: b, distance: a, ignoreLocation: p }); if (x = Math.min(O, x), S = m + k, w) for (var j = 0; j < k;)_[m + j] = 1, j += 1 } S = -1; for (var I = [], C = 1, E = k + M, $ = 1 << k - 1, P = 0; P < k; P += 1) { for (var N = 0, D = E; N < D;) { var z = R(t, { errors: P, currentLocation: b + D, expectedLocation: b, distance: a, ignoreLocation: p }); z <= x ? N = D : E = D, D = Math.floor((E - N) / 2 + N) } E = D; var K = Math.max(1, b - D + 1), q = f ? M : Math.min(b + D, M) + k, W = Array(q + 2); W[q + 1] = (1 << P) - 1; for (var J = q; J >= K; J -= 1) { var T = J - 1, U = n[e.charAt(T)]; if (w && (_[T] = +!!U), W[J] = (W[J + 1] << 1 | 1) & U, P && (W[J] |= (I[J + 1] | I[J]) << 1 | 1 | I[J + 1]), W[J] & $ && (C = R(t, { errors: P, currentLocation: T, expectedLocation: b, distance: a, ignoreLocation: p })) <= x) { if (x = C, (S = T) <= b) break; K = Math.max(1, 2 * b - S) } } var V = R(t, { errors: P + 1, currentLocation: b, expectedLocation: b, distance: a, ignoreLocation: p }); if (V > x) break; I = W } var B = { isMatch: S >= 0, score: Math.max(.001, C) }; if (w) { var G = F(_, d); G.length ? g && (B.indices = G) : B.isMatch = !1 } return B }(e, n, i, { location: c + o, distance: a, threshold: s, findAllMatches: u, minMatchCharLength: h, includeMatches: r, ignoreLocation: f }), p = y.isMatch, m = y.score, k = y.indices; p && (g = !0), v += m, p && k && (d = [].concat(l(d), l(k))) })); var y = { isMatch: g, score: g ? v / this.chunks.length : 1 }; return g && r && (y.indices = d), y } }]), e }(), D = function () { function e(n) { t(this, e), this.pattern = n } return r(e, [{ key: \"search\", value: function () { } }], [{ key: \"isMultiMatch\", value: function (e) { return z(e, this.multiRegex) } }, { key: \"isSingleMatch\", value: function (e) { return z(e, this.singleRegex) } }]), e }(); function z(e, t) { var n = e.match(t); return n ? n[1] : null } var K = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = e === this.pattern; return { isMatch: t, score: t ? 0 : 1, indices: [0, this.pattern.length - 1] } } }], [{ key: \"type\", get: function () { return \"exact\" } }, { key: \"multiRegex\", get: function () { return /^=\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^=(.*)$/ } }]), i }(D), q = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = -1 === e.indexOf(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"inverse-exact\" } }, { key: \"multiRegex\", get: function () { return /^!\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^!(.*)$/ } }]), i }(D), W = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = e.startsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, this.pattern.length - 1] } } }], [{ key: \"type\", get: function () { return \"prefix-exact\" } }, { key: \"multiRegex\", get: function () { return /^\\^\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^\\^(.*)$/ } }]), i }(D), J = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = !e.startsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"inverse-prefix-exact\" } }, { key: \"multiRegex\", get: function () { return /^!\\^\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^!\\^(.*)$/ } }]), i }(D), T = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = e.endsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [e.length - this.pattern.length, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"suffix-exact\" } }, { key: \"multiRegex\", get: function () { return /^\"(.*)\"\\$$/ } }, { key: \"singleRegex\", get: function () { return /^(.*)\\$$/ } }]), i }(D), U = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = !e.endsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"inverse-suffix-exact\" } }, { key: \"multiRegex\", get: function () { return /^!\"(.*)\"\\$$/ } }, { key: \"singleRegex\", get: function () { return /^!(.*)\\$$/ } }]), i }(D), V = function (e) { a(i, e); var n = f(i); function i(e) { var r, o = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, c = o.location, a = void 0 === c ? A.location : c, s = o.threshold, u = void 0 === s ? A.threshold : s, h = o.distance, f = void 0 === h ? A.distance : h, l = o.includeMatches, d = void 0 === l ? A.includeMatches : l, v = o.findAllMatches, g = void 0 === v ? A.findAllMatches : v, y = o.minMatchCharLength, p = void 0 === y ? A.minMatchCharLength : y, m = o.isCaseSensitive, k = void 0 === m ? A.isCaseSensitive : m, M = o.ignoreLocation, b = void 0 === M ? A.ignoreLocation : M; return t(this, i), (r = n.call(this, e))._bitapSearch = new N(e, { location: a, threshold: u, distance: f, includeMatches: d, findAllMatches: g, minMatchCharLength: p, isCaseSensitive: k, ignoreLocation: b }), r } return r(i, [{ key: \"search\", value: function (e) { return this._bitapSearch.searchIn(e) } }], [{ key: \"type\", get: function () { return \"fuzzy\" } }, { key: \"multiRegex\", get: function () { return /^\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^(.*)$/ } }]), i }(D), B = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { for (var t, n = 0, r = [], i = this.pattern.length; (t = e.indexOf(this.pattern, n)) > -1;)n = t + i, r.push([t, n - 1]); var o = !!r.length; return { isMatch: o, score: o ? 0 : 1, indices: r } } }], [{ key: \"type\", get: function () { return \"include\" } }, { key: \"multiRegex\", get: function () { return /^'\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^'(.*)$/ } }]), i }(D), G = [K, B, W, J, U, T, q, V], H = G.length, Q = / +(?=([^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)/; function X(e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}; return e.split(\"|\").map((function (e) { for (var n = e.trim().split(Q).filter((function (e) { return e && !!e.trim() })), r = [], i = 0, o = n.length; i < o; i += 1) { for (var c = n[i], a = !1, s = -1; !a && ++s < H;) { var u = G[s], h = u.isMultiMatch(c); h && (r.push(new u(h, t)), a = !0) } if (!a) for (s = -1; ++s < H;) { var f = G[s], l = f.isSingleMatch(c); if (l) { r.push(new f(l, t)); break } } } return r })) } var Y = new Set([V.type, B.type]), Z = function () { function e(n) { var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, i = r.isCaseSensitive, o = void 0 === i ? A.isCaseSensitive : i, c = r.includeMatches, a = void 0 === c ? A.includeMatches : c, s = r.minMatchCharLength, u = void 0 === s ? A.minMatchCharLength : s, h = r.ignoreLocation, f = void 0 === h ? A.ignoreLocation : h, l = r.findAllMatches, d = void 0 === l ? A.findAllMatches : l, v = r.location, g = void 0 === v ? A.location : v, y = r.threshold, p = void 0 === y ? A.threshold : y, m = r.distance, k = void 0 === m ? A.distance : m; t(this, e), this.query = null, this.options = { isCaseSensitive: o, includeMatches: a, minMatchCharLength: u, findAllMatches: d, ignoreLocation: f, location: g, threshold: p, distance: k }, this.pattern = o ? n : n.toLowerCase(), this.query = X(this.pattern, this.options) } return r(e, [{ key: \"searchIn\", value: function (e) { var t = this.query; if (!t) return { isMatch: !1, score: 1 }; var n = this.options, r = n.includeMatches; e = n.isCaseSensitive ? e : e.toLowerCase(); for (var i = 0, o = [], c = 0, a = 0, s = t.length; a < s; a += 1) { var u = t[a]; o.length = 0, i = 0; for (var h = 0, f = u.length; h < f; h += 1) { var d = u[h], v = d.search(e), g = v.isMatch, y = v.indices, p = v.score; if (!g) { c = 0, i = 0, o.length = 0; break } if (i += 1, c += p, r) { var m = d.constructor.type; Y.has(m) ? o = [].concat(l(o), l(y)) : o.push(y) } } if (i) { var k = { isMatch: !0, score: c / i }; return r && (k.indices = o), k } } return { isMatch: !1, score: 1 } } }], [{ key: \"condition\", value: function (e, t) { return t.useExtendedSearch } }]), e }(), ee = []; function te(e, t) { for (var n = 0, r = ee.length; n < r; n += 1) { var i = ee[n]; if (i.condition(e, t)) return new i(e, t) } return new N(e, t) } var ne = \"$and\", re = \"$or\", ie = \"$path\", oe = \"$val\", ce = function (e) { return !(!e[ne] && !e[re]) }, ae = function (e) { return !!e[ie] }, se = function (e) { return !v(e) && m(e) && !ce(e) }, ue = function (e) { return i({}, ne, Object.keys(e).map((function (t) { return i({}, t, e[t]) }))) }; function he(e, t) { var n = t.ignoreFieldNorm, r = void 0 === n ? A.ignoreFieldNorm : n; e.forEach((function (e) { var t = 1; e.matches.forEach((function (e) { var n = e.key, i = e.norm, o = e.score, c = n ? n.weight : null; t *= Math.pow(0 === o && c ? Number.EPSILON : o, (c || 1) * (r ? 1 : i)) })), e.score = t })) } function fe(e, t) { var n = e.matches; t.matches = [], k(n) && n.forEach((function (e) { if (k(e.indices) && e.indices.length) { var n = { indices: e.indices, value: e.value }; e.key && (n.key = e.key.src), e.idx > -1 && (n.refIndex = e.idx), t.matches.push(n) } })) } function le(e, t) { t.score = e.score } function de(e, t) { var n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, r = n.includeMatches, i = void 0 === r ? A.includeMatches : r, o = n.includeScore, c = void 0 === o ? A.includeScore : o, a = []; return i && a.push(fe), c && a.push(le), e.map((function (e) { var n = e.idx, r = { item: t[n], refIndex: n }; return a.length && a.forEach((function (t) { t(e, r) })), r })) } var ve = function () { function e(n) { var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, i = arguments.length > 2 ? arguments[2] : void 0; t(this, e), this.options = c({}, A, {}, r), this.options.useExtendedSearch, this._keyStore = new w(this.options.keys), this.setCollection(n, i) } return r(e, [{ key: \"setCollection\", value: function (e, t) { if (this._docs = e, t && !(t instanceof E)) throw new Error(\"Incorrect 'index' type\"); this._myIndex = t || $(this.options.keys, this._docs, { getFn: this.options.getFn }) } }, { key: \"add\", value: function (e) { k(e) && (this._docs.push(e), this._myIndex.add(e)) } }, { key: \"remove\", value: function () { for (var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : function () { return !1 }, t = [], n = 0, r = this._docs.length; n < r; n += 1) { var i = this._docs[n]; e(i, n) && (this.removeAt(n), n -= 1, r -= 1, t.push(i)) } return t } }, { key: \"removeAt\", value: function (e) { this._docs.splice(e, 1), this._myIndex.removeAt(e) } }, { key: \"getIndex\", value: function () { return this._myIndex } }, { key: \"search\", value: function (e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.limit, r = void 0 === n ? -1 : n, i = this.options, o = i.includeMatches, c = i.includeScore, a = i.shouldSort, s = i.sortFn, u = i.ignoreFieldNorm, h = g(e) ? g(this._docs[0]) ? this._searchStringList(e) : this._searchObjectList(e) : this._searchLogical(e); return he(h, { ignoreFieldNorm: u }), a && h.sort(s), y(r) && r > -1 && (h = h.slice(0, r)), de(h, this._docs, { includeMatches: o, includeScore: c }) } }, { key: \"_searchStringList\", value: function (e) { var t = te(e, this.options), n = this._myIndex.records, r = []; return n.forEach((function (e) { var n = e.v, i = e.i, o = e.n; if (k(n)) { var c = t.searchIn(n), a = c.isMatch, s = c.score, u = c.indices; a && r.push({ item: n, idx: i, matches: [{ score: s, value: n, norm: o, indices: u }] }) } })), r } }, { key: \"_searchLogical\", value: function (e) { var t = this, n = function (e, t) { var n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, r = n.auto, i = void 0 === r || r, o = function e(n) { var r = Object.keys(n), o = ae(n); if (!o && r.length > 1 && !ce(n)) return e(ue(n)); if (se(n)) { var c = o ? n[ie] : r[0], a = o ? n[oe] : n[c]; if (!g(a)) throw new Error(x(c)); var s = { keyId: j(c), pattern: a }; return i && (s.searcher = te(a, t)), s } var u = { children: [], operator: r[0] }; return r.forEach((function (t) { var r = n[t]; v(r) && r.forEach((function (t) { u.children.push(e(t)) })) })), u }; return ce(e) || (e = ue(e)), o(e) }(e, this.options), r = this._myIndex.records, i = {}, o = []; return r.forEach((function (e) { var r = e.$, c = e.i; if (k(r)) { var a = function e(n, r, i) { if (!n.children) { var o = n.keyId, c = n.searcher, a = t._findMatches({ key: t._keyStore.get(o), value: t._myIndex.getValueForItemAtKeyId(r, o), searcher: c }); return a && a.length ? [{ idx: i, item: r, matches: a }] : [] } switch (n.operator) { case ne: for (var s = [], u = 0, h = n.children.length; u < h; u += 1) { var f = e(n.children[u], r, i); if (!f.length) return []; s.push.apply(s, l(f)) } return s; case re: for (var d = [], v = 0, g = n.children.length; v < g; v += 1) { var y = e(n.children[v], r, i); if (y.length) { d.push.apply(d, l(y)); break } } return d } }(n, r, c); a.length && (i[c] || (i[c] = { idx: c, item: r, matches: [] }, o.push(i[c])), a.forEach((function (e) { var t, n = e.matches; (t = i[c].matches).push.apply(t, l(n)) }))) } })), o } }, { key: \"_searchObjectList\", value: function (e) { var t = this, n = te(e, this.options), r = this._myIndex, i = r.keys, o = r.records, c = []; return o.forEach((function (e) { var r = e.$, o = e.i; if (k(r)) { var a = []; i.forEach((function (e, i) { a.push.apply(a, l(t._findMatches({ key: e, value: r[i], searcher: n }))) })), a.length && c.push({ idx: o, item: r, matches: a }) } })), c } }, { key: \"_findMatches\", value: function (e) { var t = e.key, n = e.value, r = e.searcher; if (!k(n)) return []; var i = []; if (v(n)) n.forEach((function (e) { var n = e.v, o = e.i, c = e.n; if (k(n)) { var a = r.searchIn(n), s = a.isMatch, u = a.score, h = a.indices; s && i.push({ score: u, key: t, value: n, idx: o, norm: c, indices: h }) } })); else { var o = n.v, c = n.n, a = r.searchIn(o), s = a.isMatch, u = a.score, h = a.indices; s && i.push({ score: u, key: t, value: o, norm: c, indices: h }) } return i } }]), e }(); return ve.version = \"6.4.6\", ve.createIndex = $, ve.parseIndex = function (e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.getFn, r = void 0 === n ? A.getFn : n, i = e.keys, o = e.records, c = new E({ getFn: r }); return c.setKeys(i), c.setIndexRecords(o), c }, ve.config = A, function () { ee.push.apply(ee, arguments) }(Z), ve }, \"object\" == typeof exports && \"undefined\" != typeof module ? module.exports = t() : \"function\" == typeof define && define.amd ? define(t) : (e = e || self).Fuse = t();\n", "/*\n * Some notes on how this works...\n *\n * paletteData is passed into the constructor and is the initial list of items\n * these are TurboAdminMenuItem objects\n *\n * At any point, buildPaletteItems() can be called to turn the paletteData\n * into an array of \"li\" nodes.\n *\n * updatePaletteItems inserts the paletteItems into the \"ul\" list and sets the\n * selectedElement\n *\n * The selectedItem is always one of the paletteItems\n *\n * paletteSearch rebuilds the paletteItems from the paletteData using\n * buildPaletteItems, and then filters the list with FuseJS\n */\n\nimport Fuse from './fuse-6.4.6.js';\nimport TurboAdminMenuItem from './class-turbo-admin-menu-item';\nimport ContentApi from './class-content-api.js';\n\nexport default class TurboAdminPalette {\n\n\tconstructor(paletteData, options) {\n\n\t\tconsole.log('Initialising TurboAdmin');\n\n        this.options = options;\n\n        /** @type {HTMLDivElement} */\n        this.paletteElement      = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-container'));\n        /** @type {HTMLDivElement} */\n        this.paletteInnerElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette'));\n\t\t/** @type {HTMLInputElement} */\n        this.paletteInputElement = /** @type {HTMLInputElement} */ (document.getElementById('ta-command-palette-input'));\n\t\t/** @type {HTMLUListElement} */\n        this.paletteItemsElement = /** @type {HTMLUListElement} */ (document.getElementById('ta-command-palette-items'));\n\n\t\t// Get palette data\n\t\tthis.paletteData = paletteData;\n\n        // Get post type data from API\n        this.postTypes = [];\n        this.fetchPostTypes();\n\n        // paletteItems is the list of 'li' elements used to build the palette\n        this.paletteItems = [];\n\n        // itemIndex is a \"cache\" of URLs used to check if we already\n        // have an item in the palette\n        this.itemIndex = {};\n\n        // Convert into LI elements\n        this.buildPaletteItems();\n\n\n\t\tthis.selectedItem = this.paletteItems[0];\n        this.openedSubMenu = null;\n        this.selectedSubItem = null;\n\n\t\t// Add them to the DOM\n\t\tthis.updatePaletteItems();\n\n        // Set state\n        this.navigating = false;\n        this.debounceTimeout;\n\n\t\tthis.paletteFuseOptions = [];\n\t\tthis.paletteFuse = null;\n\n\t\tif (typeof (Fuse) !== 'function') {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.paletteFuseOptions = {\n\t\t\tkeys: ['innerText'],\n\t\t}\n\n\t\tthis.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);\n\n\t\tdocument.addEventListener('keydown', e => this.handleGlobalKey(e));\n\n\t\tthis.paletteElement.addEventListener('click', e => {\n\t\t\tthis.checkForPaletteItemClick(e);\n            this.checkForClickToClose(e);\n\t\t});\n\n        this.paletteItemsElement.addEventListener('mouseover', e => {\n            this.setHoveredItem(e.target);\n        });\n\t}\n\n    htmlDecode(input) {\n        var doc = new DOMParser().parseFromString(input, \"text/html\");\n        return doc.documentElement.textContent;\n    }\n\n    isMac() {\n        return navigator.platform.startsWith('Mac');\n    }\n\n    metaPressed(e) {\n        return this.isMac() ? e.metaKey : e.ctrlKey;\n    }\n\n    fetchPostTypes() {\n        if (! globalThis.contentApi.active) {\n            this.postTypes = [];\n            return;\n        }\n\n        globalThis.contentApi.get('types').then(\n            response => {\n                response.json().then(\n                    types => {\n                        this.postTypes = types;\n                    }\n                );\n            }\n        );\n    }\n\n\tbuildPaletteItems() {\n        this.paletteItems = [];\n        this.itemIndex = {};\n\n\t\tthis.paletteData.forEach(item => {\n\t\t\tconst li = document.createElement('li');\n\t\t\tconst a = document.createElement('a');\n\t\t\tli.appendChild(a);\n\t\t\ta.href = item.action;\n\t\t\tlet title = item.title;\n\t\t\tif (item.parentTitle) {\n\t\t\t\ttitle = item.parentTitle + \": \" + title;\n\t\t\t}\n\t\t\ta.innerHTML = title;\n            this.addPaletteListItem(li);\n\t\t});\n\t}\n\n    // This takes a 'li' element and adds it to the paletteItems.\n    // It also updates any caches and stuff.\n    addPaletteListItem(listItem) {\n        this.paletteItems.push(listItem);\n\n        const link = listItem.querySelector('a');\n        if (link) {\n            this.itemIndex[link.href] = 1;\n        }\n    }\n\n    contentItemExists(url) {\n        return Boolean(this.itemIndex[url]);\n    }\n\n    injectContentItems(contentItems) {\n        console.log('Injecting items');\n\n        // We'll need this in the loop below.\n        const profileLinkElem = document.getElementById('wp-admin-bar-edit-profile');\n        let profileLink = null;\n        if (profileLinkElem) {\n            profileLink = profileLinkElem.querySelector('a').href;\n        }\n\n        // TODO: Can we not do this on every content item inject?\n        // Check for presence of Oxygen Page builder\n        /** @type {HTMLElement|string|Number} */\n        let oxygenLinkElem = document.getElementById('toplevel_page_ct_dashboard_page');\n        // Also check for a menu bar item\n        if (! oxygenLinkElem) {\n            oxygenLinkElem = document.getElementById('wp-admin-bar-oxygen_admin_bar_menu');\n        }\n        // Check to see if Oxygen link is cached\n        if (! oxygenLinkElem) {\n            oxygenLinkElem = Number(window.localStorage.getItem('ta-has-oxygen-builder'));\n        }\n        // Save Oxygen builder status\n        window.localStorage.setItem('ta-has-oxygen-builder', Boolean(oxygenLinkElem) ? '1' : '0' );\n\n        if (contentItems.length > 0) {\n            contentItems.forEach(item => {\n                const itemTitle = item.title;\n                // const itemTitle = item.title.rendered;\n                const itemType = item.subtype;\n                const itemUrl = item.url;\n\n                // console.log('Adding item: ' + itemTitle);\n\n                // // Check if item already exists\n                if (this.contentItemExists(itemUrl)) {\n                    console.log('Not adding duplicate');\n                    return;\n                }\n\n                const itemTypeName = this.postTypes[itemType] ? this.postTypes[itemType].name : itemType;\n                const title = `${itemTitle} (${itemTypeName})`;\n\n                const li = document.createElement('li');\n                const a = document.createElement('a');\n                const subMenu = document.createElement('div');\n                const subMenuTitle = document.createElement('div');\n                const subMenuItems = document.createElement('ul');\n                subMenu.classList.add('ta-submenu');\n                subMenuTitle.classList.add('ta-submenu-title');\n\n                subMenuTitle.textContent = this.htmlDecode(itemTitle);\n                subMenuItems.classList.add('ta-submenu-items');\n                subMenu.appendChild(subMenuTitle);\n                subMenu.appendChild(subMenuItems);\n\n                const subMenuItem1 = document.createElement('li');\n                const subMenuLink1 = document.createElement('a');\n                subMenuLink1.innerText = \"View\";\n                subMenuLink1.href = itemUrl;\n                subMenuItem1.appendChild(subMenuLink1);\n                subMenuItems.appendChild(subMenuItem1);\n\n                if (profileLink) {\n                    // Need to get edit URL. This seems like the best way for now.\n                    const editLink = profileLink.replace('profile.php', `post.php?post=${item.id}&action=edit`);\n\n                    const subMenuItem2 = document.createElement('li');\n                    const subMenuLink2 = document.createElement('a');\n                    subMenuLink2.innerText = \"Edit\";\n                    subMenuLink2.href = editLink;\n                    subMenuItem2.appendChild(subMenuLink2);\n                    subMenuItems.appendChild(subMenuItem2);\n                }\n\n                if (oxygenLinkElem) {\n                    // Oxygen Edit Links are like: https://example.com.com/?page_id=26&ct_builder=true&ct_inner=true\n                    const oxygenLink = globalThis.taWp.home + `?page_id=${item.id}&ct_builder=true&ct_inner=true`;\n\n                    const subMenuItem3 = document.createElement('li');\n                    const subMenuLink3 = document.createElement('a');\n                    subMenuLink3.innerText = \"Edit with Oxygen\";\n                    subMenuLink3.href = oxygenLink;\n                    subMenuItem3.appendChild(subMenuLink3);\n                    subMenuItems.appendChild(subMenuItem3);\n                }\n\n                const subMenuItem3 = document.createElement('li');\n                const subMenuLink3 = document.createElement('a');\n                subMenuLink3.innerText = \"Copy link\";\n                // Because this is an href we're setting it gets URI encoded!\n                subMenuLink3.href = itemUrl;\n                subMenuLink3.setAttribute('data-action', 'clipboard');\n                subMenuItem3.appendChild(subMenuLink3);\n                subMenuItems.appendChild(subMenuItem3);\n\n\n                li.classList.add('ta-has-child-menu');\n\n                li.appendChild(a);\n                li.appendChild(subMenu);\n\n                a.href = itemUrl;\n                a.innerHTML = title;\n                this.addPaletteListItem(li);\n            })\n        }\n\n        // Reset the search to work on the new items\n        this.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);\n        this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map(i => i.item);\n\n        this.updatePaletteItems();\n    }\n\n\t/**\n     * Handle global keypresses (at document level). Note that other key presses\n     * are handled by paletteActions()\n     *\n     * @param {KeyboardEvent} e\n     */\n    async handleGlobalKey(e) {\n\t\tif (this.shortcutKeysPressed(e)) {\n            e.preventDefault();\n            e.stopPropagation();\n\t\t\tif (this.paletteShown()) {\n\t\t\t\tthis.hidePalette();\n\t\t\t} else {\n\t\t\t\tthis.showPalette();\n\t\t\t}\n\t\t}\n\n\t\tif (e.code === 'Escape' && this.paletteShown()) {\n\t\t\tif (this.isSubMenuOpen()){\n                this.closeSubMenu();\n            } else {\n                this.hidePalette();\n            }\n\t\t}\n\n        if (this.paletteShown()) {\n            await this.paletteActions(e);\n\t\t}\n\t}\n\n\tshortcutKeysPressed(keyEvent) {\n        // The reduce here works through all the different possible key combos\n        // (more than one can be specified in options)\n\t\tconst keysPressed = this.options.shortcutKeys.reduce(\n\t\t\t(keyPressed, combo) => {\n\t\t\t\tif (keyPressed) {\n\t\t\t\t\treturn keyPressed;\n\t\t\t\t}\n                return ((!navigator.platform.startsWith('Mac')) || (combo.meta === keyEvent.metaKey))\n                    && (combo.alt === keyEvent.altKey)\n                    && (combo.shift === keyEvent.shiftKey)\n                    && (combo.ctrl === keyEvent.ctrlKey)\n                    && (\n                        keyEvent.code === 'Key' + combo.key.toUpperCase()\n                        || ( combo.key === ' ' && keyEvent.code.toUpperCase() === 'SPACE' )\n                    );\n            }, false);\n\t\treturn keysPressed;\n\t}\n\n    async debouncedPaletteSearchAndUpdate() {\n        // If search string is not long enough for content search, then\n        // run without debounce.\n        if (\n            ( this.paletteInputElement.value !== '' && this.paletteInputElement.value.length <= 2)\n            || this.postTypes === [] ) {\n            this.debounceTimeout = null;\n            await this.paletteSearchAndUpdate();\n            return;\n        }\n        // If timer is null, reset it to 500ms and run your functions.\n        // Otherwise, wait until timer is cleared\n        if (!this.debounceTimeout) {\n            this.debounceTimeout = setTimeout(async function () {\n                // Reset timeout\n                this.debounceTimeout = null;\n\n                // Run the search function\n                await this.paletteSearchAndUpdate();\n            }.bind(this), 750);\n        }\n    }\n\n\t/**\n     * Handle (non-global) keypresses on the palette\n     *\n     * @param {KeyboardEvent} e\n     * @returns {Promise}\n     */\n    async paletteActions(e) {\n\t\tif (e.code === 'ArrowDown' && this.paletteShown()) {\n\t\t\te.preventDefault();\n\t\t\tthis.moveDown();\n\t\t\treturn;\n\t\t}\n\t\tif (e.code === 'ArrowUp' && this.paletteShown()) {\n\t\t\te.preventDefault();\n\t\t\tthis.moveUp();\n\t\t\treturn;\n\t\t}\n\t\tif (e.code === 'Enter' && this.paletteShown()) {\n            this.doAction(this.metaPressed(e));\n            return;\n\t\t}\n        if (this.isSubMenuOpen()) {\n            return;\n        }\n\t\tawait this.debouncedPaletteSearchAndUpdate();\n\t}\n\n\tshowPalette() {\n\t\tthis.paletteInputElement.value = '';\n        this.paletteItemsElement.scrollTop = 0;\n\t\tthis.paletteElement?.classList.add('active');\n\t\tthis.paletteInputElement?.focus();\n\t}\n\n\thidePalette() {\n        this.navigating = false;\n\t\tthis.paletteElement?.classList.remove('active');\n        this.paletteInputElement.value = '';\n        this.paletteInputElement.blur();\n        if (this.isSubMenuOpen()) {\n            this.closeSubMenu();\n        }\n\t}\n\n\tpaletteShown() {\n\t\treturn this.paletteElement?.classList.contains('active');\n\t}\n\n    checkForPaletteItemClick(e) {\n        if (e.target.tagName === 'A') {\n            e.preventDefault();\n            if (this.isSubMenuOpen()) {\n                this.selectedSubItem = e.target.closest('li');\n            } else {\n                this.selectedItem = e.target.closest('li');\n            }\n            this.setSelectedElement();\n\n            this.doAction(this.metaPressed(e));\n        }\n    }\n\n\tcheckForClickToClose(e) {\n\t\tif (e.target.id === this.paletteElement.id) {\n\t\t\tthis.hidePalette();\n\t\t}\n\t}\n\n\tsetSelectedElement() {\n        if (this.isSubMenuOpen()) {\n            this.paletteItemsElement?.querySelectorAll('.ta-submenu.active li.selected')?.forEach(e => e.classList.remove('selected'));\n            this.selectedSubItem.classList.add('selected');\n        } else {\n            this.paletteItemsElement?.querySelectorAll('li.selected')?.forEach(e => e.classList.remove('selected'));\n            if (this.selectedItem) {\n                this.selectedItem.classList.add('selected');\n                this.scrollList();\n            }\n        }\n\t}\n\n\tscrollList() {\n\t\t// Scrolling up\n\t\tif (this.selectedItem.offsetTop < this.paletteItemsElement.scrollTop) {\n\t\t\tthis.paletteItemsElement.scrollTop = this.selectedItem.offsetTop;\n\t\t}\n\t\t// Scrolling down\n\t\tif (this.selectedItem.offsetTop + this.selectedItem.offsetHeight > this.paletteItemsElement.offsetHeight + this.paletteItemsElement.scrollTop) {\n\t\t\tthis.paletteItemsElement.scrollTop = this.selectedItem.offsetTop + this.selectedItem.offsetHeight - this.paletteItemsElement.offsetHeight;\n\t\t}\n\t}\n\n    setHoveredItem(element) {\n        // Only do this for li's\n        if ('LI' === element.tagName) {\n            this.navigating = true;\n            if (this.isSubMenuOpen()) {\n                this.selectedSubItem = element;\n            } else {\n                this.selectedItem = element;\n            }\n            this.setSelectedElement();\n        }\n    }\n\n\tmoveDown() {\n        if (this.isSubMenuOpen()) {\n            const nextItem = this.selectedSubItem.nextElementSibling;\n            this.navigating = true;\n            if (nextItem) {\n                this.selectedSubItem = nextItem;\n                this.setSelectedElement();\n            }\n        } else {\n            const nextItem = this.selectedItem.nextElementSibling;\n            this.navigating = true;\n            if (nextItem) {\n                this.selectedItem = nextItem;\n                this.setSelectedElement();\n            }\n        }\n\t}\n\n\tmoveUp() {\n        if (this.isSubMenuOpen()) {\n            const prevItem = this.selectedSubItem.previousElementSibling;\n            this.navigating = true;\n            if (prevItem) {\n                this.selectedSubItem = prevItem;\n                this.setSelectedElement();\n            }\n        } else {\n            const prevItem = this.selectedItem.previousElementSibling;\n            this.navigating = true;\n            if (prevItem) {\n                this.selectedItem = prevItem;\n                this.setSelectedElement();\n            }\n        }\n    }\n\n    isSubMenuOpen() {\n        return null !== this.openedSubMenu;\n    }\n\n    openSubMenu(subMenuElement) {\n        // Set height in case main menu is smaller than sub menu\n        const subMenuHeight = subMenuElement.offsetHeight;\n        this.paletteItemsElement.style.minHeight = subMenuHeight + \"px\";\n        subMenuElement.classList.add('active');\n\n\n        this.selectedSubItem = subMenuElement.querySelector('li');\n        this.openedSubMenu = subMenuElement;\n        this.setSelectedElement();\n\n        this.paletteInputElement.disabled = true;\n        // Blur the input so that keys can continue to be captured\n        this.paletteInputElement.blur();\n    }\n\n    closeSubMenu(subMenuElement = null) {\n        if (null === subMenuElement) {\n            subMenuElement = document.querySelector('.ta-submenu.active');\n        }\n        subMenuElement.classList.remove('active');\n        this.selectedSubItem.classList.remove('active');\n        this.paletteItemsElement.style.minHeight = 'auto';\n        this.selectedSubItem = null;\n        this.openedSubMenu = null;\n        this.paletteInputElement.disabled = false;\n        this.paletteInputElement.focus();\n    }\n\n\tdoAction(metaPressed = false) {\n        if (this.isSubMenuOpen()) {\n            this.actOnItem(this.selectedSubItem, metaPressed);\n            return;\n        }\n        if (this.selectedItem.classList.contains('ta-has-child-menu')) {\n            const subMenu = this.selectedItem.querySelector('.ta-submenu');\n            this.openSubMenu(subMenu);\n            return;\n        }\n\n        this.actOnItem(this.selectedItem, metaPressed);\n    }\n\n    actOnItem(item, metaPressed) {\n        this.hidePalette();\n        const link = item.querySelector('a');\n        const url = link.href;\n\n        if ('clipboard' === link.dataset.action) {\n            navigator.clipboard.writeText(url);\n            return;\n        }\n\n        if (metaPressed) {\n            window.open(url, '_blank');\n        } else {\n            window.location = url;\n        }\n    }\n\n\tselectedItemDisplayed() {\n\t\treturn Array.from(this.paletteItemsElement.childNodes).includes(this.selectedItem);\n\t}\n\n\tasync paletteSearchAndUpdate() {\n\t\tawait this.paletteSearch();\n\t\tthis.updatePaletteItems();\n\t}\n\n\tasync paletteSearch() {\n        // Get the value...\n        // const response = await globalThis.contentApi.get('posts', { search: this.paletteInputElement.value, per_page: 100, status: ['publish', 'future', 'draft', 'pending', 'private'] });\n\n        this.buildPaletteItems();\n\n        if (this.paletteInputElement.value !== '') {\n            // Reset the search to work on the new items\n            this.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);\n            this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map(i => i.item);\n        }\n\n        // Content search - don't search everything!\n        if (globalThis.contentApi.active && this.postTypes !== [] && this.paletteInputElement.value.length > 2) {\n            this.paletteInnerElement.classList.add('loading');\n\n            globalThis.contentApi.getPosts(this.paletteInputElement.value)\n                .then(\n                    results => {\n                            this.injectContentItems(results);\n                            this.paletteInnerElement.classList.remove('loading');\n                    }\n                )\n        }\n\t}\n\n\tupdatePaletteItems() {\n\t\tconst newItems = document.createElement('ul');\n\t\tnewItems.id = 'ta-command-palette-items';\n\n\t\tthis.paletteItems.forEach(i => {\n\t\t\tnewItems.appendChild(i);\n\t\t})\n\n\t\tthis.paletteItemsElement.replaceChildren(...newItems.children);\n\n\t\tif (!this.navigating || !this.selectedItemDisplayed()) {\n\t\t\tthis.selectedItem = this.paletteItems[0];\n\t\t}\n\n\t\tthis.setSelectedElement();\n\t}\n\n}\n", "export default class TurboAdminMenuItem {\n\n\tconstructor(title, action, parentTitle, noCache = false) {\n\t\tthis.title = title;\n\t\tthis.action = action;\n\t\tthis.parentTitle = parentTitle;\n        this.noCache = noCache;\n\t}\n\n    sameAs(item) {\n        return item.title === this.title &&\n            item.action === this.action &&\n            item.parentTitle === this.parentTitle;\n    }\n}\n", "/**\n * This class is an abstraction of the browser extension storage API\n * (see https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage)\n * but that falls back to using regular localStorage if we're not in a\n * browser extension.\n *\n * This exists so that the same API can be used from both the browser\n * extension AND the plugin version of Turbo Admin.\n *\n * Note that for the extension, data saved is \"global\" to the extension\n * and is NOT site specific.\n */\nexport default class Storage {\n\n    /**\n     * Constructor - detects where code is running and sets the local\n     * store appropriately.\n     */\n    constructor() {\n        /** @type {null|storageStorageArea|WindowLocalStorage} */\n        this.store = null;\n\n        if ('undefined' === typeof (browser)) {\n            this.store = window.localStorage;\n        } else {\n            this.store = browser.storage.local;\n        }\n    }\n\n    /**\n     * Set/save extension data. Must be passed an object with key/value\n     * pairs.\n     *\n     * @param {Object} dataObject\n     */\n    async set(dataObject) {\n        if ('undefined' === typeof (browser)) {\n            const keys = Object.keys(dataObject);\n            keys.forEach(key => this.store.setItem(key, JSON.stringify(dataObject[key])));\n        } else {\n            await this.store.set(dataObject);\n        }\n    }\n\n    /**\n     * Get data from the extension's storage.\n     *\n     * Note that fetched data will be a object with the key as a\n     * property.\n     *\n     * @param {String} key\n     * @returns {Promise<Object>}\n     */\n    async get(key) {\n        if ('undefined' === typeof (browser)) {\n            let returnObj = {};\n            let item = this.store.getItem(key);\n            if (! item) {\n                return returnObj;\n            }\n            let itemObject = null;\n            try {\n                itemObject = JSON.parse(this.store.getItem(key));\n            } catch (e) {\n                itemObject = null;\n            }\n            returnObj[key] = itemObject;\n            return returnObj;\n        } else {\n            return await this.store.get(key);\n        }\n    }\n\n}\n", "import Storage from './class-storage.js';\n\nexport default class ContentApi {\n\n    constructor() {\n        // this.discoverApiRoot().then(e => null);\n        // console.log('Discovered API base: ', this.apiBase);\n        this.active = false;\n        this.store = new Storage();\n\n        // This is used to \"cache\" duplicate requests.\n        // It's an object because it will have search strings as keys\n        this.cache = {};\n    }\n\n    async discoverApiRoot() {\n        let wpApiSettings = null;\n        this.storageKey = 'wpApiSettings.' + globalThis.taWp.home;\n\n        // Could be in the wp-api-request-js-extra (on wp-admin side)\n        const wpApiSettingsScript = document.getElementById('wp-api-request-js-extra');\n        if (wpApiSettingsScript) {\n            const wpApiSettingsString = wpApiSettingsScript.innerHTML.match(/var\\s+wpApiSettings\\s+=\\s+(.+);/)[1];\n            const wpApiSettings = JSON.parse(wpApiSettingsString);\n            const objectToSave = {};\n            objectToSave[this.storageKey] = wpApiSettings;\n            await this.store.set(objectToSave);\n            this.apiRoot = wpApiSettings.root;\n            this.apiBase = this.apiRoot + wpApiSettings.versionString;\n            this.apiNonce = wpApiSettings.nonce;\n            // Clear the nonce if one is set and we're not logged in\n            this.maybeExpireNonce(wpApiSettings);\n            this.active = true;\n            return;\n        }\n\n        // Getting from extension storage returns a object with the key\n        // as the key. Which is weird.\n        wpApiSettings = await this.store.get(this.storageKey);\n        if (wpApiSettings\n            && Object.keys(wpApiSettings).length !== 0\n            && wpApiSettings[this.storageKey]\n            && 'object' === typeof(wpApiSettings[this.storageKey])) {\n            // Get the key'ed item out of the object\n            wpApiSettings = wpApiSettings[this.storageKey];\n            this.apiRoot = wpApiSettings.root;\n            this.apiBase = this.apiRoot + wpApiSettings.versionString;\n            this.apiNonce = wpApiSettings.nonce;\n            // Clear the nonce if one is set and we're not logged in\n            this.maybeExpireNonce(wpApiSettings);\n            this.active = true;\n            return;\n        }\n\n        // Could be in <link rel=\"https://api.w.org/\" href=\"https://something/wp-json/\">\n        if (globalThis.taWp.apiLinkUrl) {\n            this.apiRoot = globalThis.taWp.apiLinkUrl;\n            // Just guess this\n            this.apiBase = this.apiRoot + 'wp/v2/';\n            this.active = true;\n            return;\n        }\n    }\n\n    userLoggedIn() {\n        return document.body.classList.contains('logged-in') ||\n            document.body.classList.contains('wp-admin');\n    }\n\n    async maybeExpireNonce(wpApiSettings) {\n        if (wpApiSettings?.nonce && ! this.userLoggedIn()) {\n            // Clear apiSetting nonce\n            this.apiNonce = null;\n            wpApiSettings.nonce = null;\n            const objectToSave = {};\n            objectToSave[this.storageKey] = wpApiSettings;\n            await this.store.set(objectToSave);\n        }\n    }\n\n    makeParamString(data) {\n        const params = new URLSearchParams();\n\n        Object.keys(data).forEach(paramKey => {\n            // Handle arrays\n            if (Array.isArray(data[paramKey])) {\n                const arrayParamKey = paramKey + '[]';\n                data[paramKey].forEach( item => params.append(arrayParamKey, item));\n            } else {\n                params.append(paramKey, data[paramKey]);\n            }\n        });\n\n        return params.toString();\n    }\n\n    statuses() {\n        if (this.apiNonce) {\n            return [\"publish\", \"future\", \"draft\", \"pending\", \"private\"];\n        } else {\n            return [\"publish\"];\n        }\n    }\n\n    types() {\n        return globalThis.turboAdmin.turboAdminPalette.postTypes;\n    }\n\n    async getPosts(searchString) {\n        // Check the cache\n        if (undefined !== this.cache[searchString]) {\n            return this.cache[searchString];\n        }\n\n        // Fetch results\n        const response = await this.get(\n            // \"posts\",\n            \"search\",\n            {\n                search: searchString,\n                per_page: 100,\n                // status: this.statuses(),\n                type: 'post',\n                subtype: 'any'\n            }\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache[searchString] = result;\n\n        return result;\n    }\n\n    async get(path, data = {}) {\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n        }\n\n        // Add the nonce if there is one\n        if (this.apiNonce) {\n            data._wpnonce = this.apiNonce;\n        }\n\n        const params = this.makeParamString(data);\n\n        const response = await fetch(`${this.apiBase}${path}/?${params}`);\n\n        return response;\n    }\n\n}\n", "/**\n * It's impossible to change the setting to off, because the\n * extension's content script runs in a sandbox and can't access\n * the wp object. But we can just toggle the class every time.\n */\nexport default class TurboAdminWpBlockEditorFullscreenKill {\n\n    constructor() {\n\n        const attrObserver = new MutationObserver((mutations) => {\n            mutations.forEach(mu => {\n                // Check if we already killed fullscreen\n                // if (document.body.classList.contains('turbo-admin-killed-fullscreen')) {\n                //     return;\n                // }\n\n                if (mu.type !== \"attributes\" && mu.attributeName !== \"class\") {\n                    return;\n                }\n\n                if (mu.target.classList.contains('is-fullscreen-mode')) {\n                    this.killFullScreenEditor();\n                }\n            });\n        });\n\n        attrObserver.observe(document.body, { attributes: true });\n\n        // Also attempt a kill now in case it's already appeared.\n        this.killFullScreenEditor();\n    }\n\n    killFullScreenEditor() {\n        if (! document.body.classList.contains('is-fullscreen-mode')) {\n            return;\n        }\n\n        document.body.classList.remove('is-fullscreen-mode');\n        document.body.classList.add('turbo-admin-killed-fullscreen');\n\n        const newStyles = document.createElement('style');\n        newStyles.innerHTML = \"body.turbo-admin-killed-fullscreen .edit-post-fullscreen-mode-close { display: none; }\";\n        document.body.appendChild(newStyles);\n    }\n}\n", "/**\n *\n */\nexport default class TurboAdminWpBlockEditorWelcomeGuideKill {\n\n    constructor() {\n\n        const attrObserver = new MutationObserver((mutations) => {\n            mutations.forEach(mu => {\n                // Check if we already killed the modal\n                if (document.body.classList.contains('ta-killed-post-welcome-guide')) {\n                    return;\n                }\n\n                if (mu.type !== \"attributes\" && mu.attributeName !== \"class\") {\n                    return;\n                }\n\n                if (! mu.target.classList.contains('modal-open')) {\n                    return;\n                }\n\n                const welcomeGuide = document.querySelector('.edit-post-welcome-guide');\n                if (welcomeGuide) {\n                    this.killWelcomeGuide();\n                }\n            });\n        });\n\n        attrObserver.observe(document.body, { attributes: true });\n\n        // Also attempt a kill now in case it's already appeared.\n        this.killWelcomeGuide();\n    }\n\n    killWelcomeGuide() {\n        const welcomeGuide = document.querySelector('.edit-post-welcome-guide');\n        if (welcomeGuide) {\n            const closeButton = welcomeGuide.querySelector('.components-modal__header button');\n            if (closeButton) {\n                closeButton.click();\n                /*\n                 * Also add a class to body so we don't do it again - subsequent modals\n                 * will need to be shown as they will have been user-initiated.\n                 */\n                document.body.classList.add('ta-killed-post-welcome-guide');\n            }\n        }\n    }\n}\n", "export default class TurboAdminWpNotices {\n\n    // TODO: Handle empty IDS. Can we identify unique selectors?\n    // See spinup!\n    // Also need to only show move to panel if we can (i.e. if there's a way\n    // to identify it))\n    constructor(rememberedNoticeIds) {\n\n        // Bail if we aren't in the admin\n        if (! document.querySelector('body.wp-admin')) {\n            return;\n        }\n\n        /*\n        * These are the global notice selectors\n        */\n        this.noticeSelectors = [\n            '#wpbody-content > .notice',\n            '#wpbody-content > .wrap > .notice',\n            '#wpbody-content > .wrap > .updated',\n            '#gf_dashboard_message', // Gravity forms\n            '.jitm-banner', //\n            '.fs-notice', // I get this in Replyable\n            '#updraft-dashnotice', // Updraft backups\n            '.woocommerce-message', // WooCommerce\n            '#akismet_setup_prompt', // Akismet\n            '#wf-onboarding-plugin-header', // WordFence onboard\n            '.llar-notice-review' // Limit Login Attempts reloaded\n        ];\n\n        /*\n         * These selectors are allowed (unless explicitly denied)\n         */\n        this.allowedClasses = [\n            'notice-success',\n            'notice-error',\n            'notice-failure',\n            'updated',\n        ]\n\n        if (rememberedNoticeIds) {\n            this.rememberedNoticeIds = rememberedNoticeIds.length > 0 ? rememberedNoticeIds : [];\n        } else {\n            this.rememberedNoticeIds = [];\n        }\n\n        const toolbar = document.getElementById('wpadminbar');\n\n        if (!toolbar) {\n            return;\n        }\n\n        if (rememberedNoticeIds && rememberedNoticeIds.length > 0) {\n            rememberedNoticeIds.forEach(id => {\n                if ('string' === typeof(id) && id.length > 0) {\n                    this.noticeSelectors.push('#' + id);\n                }\n            });\n        }\n\nconsole.log('Notice Selectors', this.noticeSelectors);\n        const notices = document.querySelectorAll(this.noticeSelectors.join(','));\nconsole.log('Notices', notices);\n\n        // Add buttons to notices that can be moved\n        notices.forEach(notice => {\n            this.maybeAddIdToNotice(notice)\n\n            if (this.keepNotice(notice)) {\n                const rememberButton = document.createElement('button');\n                rememberButton.classList.add('ta-remember-notice-button');\n                rememberButton.innerText = 'Move to panel';\n\n                const forgetButton = document.createElement('button');\n                forgetButton.classList.add('ta-forget-notice-button');\n                forgetButton.innerText = 'Move to dashboard';\n\n                notice.classList.add('ta-added-pos-relative');\n\n                notice.appendChild(rememberButton);\n                notice.appendChild(forgetButton);\n\n                rememberButton.addEventListener('click', this.rememberNotice.bind(this), false, true);\n                forgetButton.addEventListener('click', this.forgetNotice.bind(this), false, true);\n            }\n        });\n\n        const noticesToHide = Array.from(notices).filter(notice => {\n            if (this.rememberedNoticeIds.includes(notice.id)) {\n                return true;\n            }\n\n            if (this.keepNotice(notice)) {\n                return false;\n            }\n\n            // Invisible\n            if (\n                notice.offsetHeight === 0 ||\n                notice.offsetWidth === 0\n            ) {\n                return false;\n            }\n\n            return true;\n        })\n\n        console.log('Notices to hide', noticesToHide)\n\n        /**\n         * Build the notices wrapper\n         */\n        /** @type {HTMLDivElement} */\n        const noticesLinkWrapper = document.createElement('div');\n        noticesLinkWrapper.id = 'ta-notices-link-wrap';\n        noticesLinkWrapper.classList.add('hide-if-no-js', 'screen-meta-toggle');\n        noticesLinkWrapper.style.margin='0 0 0 6px';\n        noticesLinkWrapper.style.float='left';\n        if (noticesToHide.length === 0) {\n            noticesLinkWrapper.style.display='none';\n        }\n\n        /**\n         * Add button\n         */\n        /** @type {HTMLButtonElement} */\n        const noticesButton = document.createElement('button');\n        noticesButton.type='button';\n        noticesButton.id='ta-notices-link';\n        noticesButton.classList.add('button', 'show-settings');\n        noticesButton.innerHTML='Notices <span id=\"ta-notice-count\">' + noticesToHide.length + '</span>';\n        noticesButton.setAttribute('aria-controls', 'ta-notices-wrap');\n\n        // This should replicate the functionality from wp-admin/js/common.js\n        // as closely as possible. But note that we can't access the common.js\n        // functions.\n        noticesButton.addEventListener('click', this.toggleNoticesPanel.bind(this), false);\n\n        /**\n         * Add button to the link wrapper\n         */\n        noticesLinkWrapper.appendChild(noticesButton);\n\n        /**\n         * Add the link wrapper to the screen-meta-links section\n         */\n        const screenMetaLinks = document.getElementById('screen-meta-links');\n        screenMetaLinks.appendChild(noticesLinkWrapper);\n\n        /**\n         * Build the panel\n         */\n        const noticesPanel = document.createElement('div');\n\n        noticesPanel.id='ta-notices-wrap';\n        noticesPanel.style.display='none';\n        noticesPanel.dataset.open='no';\n\n        const noticesPanelInner = document.createElement('div');\n        noticesPanelInner.id = 'ta-notices-panel-inner';\n\n        noticesToHide.forEach(notice => {\n            // Add 'inline' class otherwise WordPress might move them around!\n            notice.classList.add('inline');\n            // See Toolbelt's implementation: https://github.com/BinaryMoon/wp-toolbelt/blob/dev/modules/tidy-notifications/src/js/script.js\n            noticesPanelInner.append(notice);\n        });\n\n        /**\n         * Add wrap to the meta area\n         */\n        noticesPanel.appendChild(noticesPanelInner);\n        const screenMeta = document.getElementById('screen-meta');\n        screenMeta.appendChild(noticesPanel);\n\n        // Set up events on the new screen-meta item\n        // if (window.screenMeta) {\n        //     window.screenMeta.init();\n        // }\n    }\n\n    // Does the allowedClasses list say that this notice should be shown?\n    keepNotice(noticeElem) {\n        return this.allowedClasses.reduce( (found, current) => {\n            return found || noticeElem.classList.contains(current)\n        }, false);\n    }\n\n    rememberNotice(ev) {\n        const noticesLinkWrap = document.getElementById('ta-notices-link-wrap');\n        const panel = document.getElementById('wp-admin-bar-ta-notices');\n        const panelInner = document.getElementById('ta-notices-panel-inner');\n        const countElem = document.getElementById('ta-notice-count');\n        const count = parseInt(countElem.innerText, 10);\n        const notice = ev.target.closest(this.noticeSelectors.join(','));\n        const noticeId = notice.id;\n        console.log(`Remembering ${noticeId}`);\n        panelInner.appendChild(notice);\n        if (count === 0) {\n            noticesLinkWrap.style.display = 'block';\n        }\n\n        this.updateScreenMetaHeight();\n\n        countElem.innerText = parseInt(countElem.innerText, 10) + 1;\n\n        this.saveRememberedNotice(noticeId);\n    }\n\n    saveRememberedNotice(noticeId) {\n        this.rememberedNoticeIds.push(noticeId);\n\n        if ('object' === typeof(browser)) {\n            browser.runtime.sendMessage({\n                'action': 'rememberNotice',\n                'noticeId': noticeId,\n            });\n        } else {\n            window.localStorage.setItem('rememberedNoticeIds', JSON.stringify(this.rememberedNoticeIds));\n        }\n    }\n\n    forgetNotice(ev) {\n        const noticesLinkWrap = document.getElementById('ta-notices-link-wrap');\n        const panelInner = document.getElementById('ta-notices-panel-inner');\n        const countElem = document.getElementById('ta-notice-count');\n        const count = parseInt(countElem.innerText, 10);\n        const notice = ev.target.closest(this.noticeSelectors.join(','));\n        const noticeId = notice.id;\n        console.log(`Forgetting ${noticeId}`);\n\n        notice.remove();\n\n        const message = document.createElement('div');\n        const p = document.createElement('p');\n        message.classList.add('notice', 'ta-forget-notice-message');\n        p.textContent = 'Notice will be back in dashboard on next page load';\n        message.appendChild(p);\n        panelInner.appendChild(message);\n\n        this.updateScreenMetaHeight();\n\n        // I was going to to this, but we need to keep the notice about\n        // where the notice has gone.\n        // if (count === 1) {\n        //     noticesLinkWrap.style.display = 'none';\n        // }\n\n        countElem.innerText = (count - 1).toString();\n        this.saveForgottenNotice(noticeId);\n    }\n\n    saveForgottenNotice(noticeId) {\n        this.rememberedNoticeIds.push(noticeId);\n\n        if ('object' === typeof(browser)) {\n            browser.runtime.sendMessage({\n                'action': 'rememberNotice',\n                'noticeId': noticeId,\n            });\n        } else {\n            this.rememberedNoticeIds = this.rememberedNoticeIds.filter( id => id !== noticeId );\n            window.localStorage.setItem('rememberedNoticeIds', JSON.stringify(this.rememberedNoticeIds));\n        }\n    }\n\n    /*\n     * For notices without IDs we'll see if we can add an ID that's a hash of their classlist\n     */\n    maybeAddIdToNotice(notice) {\n        if (notice.id && notice.id !== '' && notice.id !=='message') {\n            return;\n        }\n\n        const classes = notice.classList;\n        notice.id = Array.from(notice.classList).join('-');\n    }\n\n    /**\n     * Detect if WordPress has already applied event handlers to our new screen meta button.\n     *\n     * If it has then WordPress/backbone.js will handle the animation and we won't have to.\n     *\n     * @returns {boolean}\n     */\n    wordpressScreenMetaEventsExist() {\n        return 'object' === typeof(window.screenMeta) && window.screenMeta.toggles.filter('#ta-notices-link').length > 0;\n    }\n\n    updateScreenMetaHeight() {\n        // Don't do this if we're relying on backbone's animation\n        if (this.wordpressScreenMetaEventsExist()) {\n            return;\n        }\n\n        const screenMeta = document.getElementById('screen-meta');\n        const noticesPanel = document.getElementById('ta-notices-wrap');\n        const height = noticesPanel.offsetHeight;\n        screenMeta.style.maxHeight = height.toString(10) + 'px';\n    }\n\n    toggleNoticesPanel(ev) {\n        // We may be in the plugin in which case we don't want to run our handler if there's\n        // a backbone handler on the button.\n        if (this.wordpressScreenMetaEventsExist()) {\n            return;\n        }\n        // Otherwise we mimic the swipe down animation.\n        const animationSeconds = 0.3;\n        const screenMeta = document.getElementById('screen-meta');\n        const noticesPanel = document.getElementById('ta-notices-wrap');\n        if (noticesPanel.dataset.open === 'no') {\n            this.toggleOtherScreenMetaTabs();\n            // Don't ask... just DON'T ask!\n            noticesPanel.dataset.open = 'yes';\n            screenMeta.style.transition = `max-height ${animationSeconds.toString(10)}s`;\n            screenMeta.style.maxHeight = '0';\n            screenMeta.style.overflow = 'hidden';\n            screenMeta.style.display = 'block';\n            noticesPanel.style.display = 'block';\n            const height = noticesPanel.offsetHeight;\n            screenMeta.style.maxHeight = height.toString(10) + 'px';\n            // setTimeout(() => {\n            //     // Nothing to do here.\n            // }, animationSeconds * 1000);\n        } else {\n            noticesPanel.dataset.open = 'no';\n            const height = noticesPanel.offsetHeight;\n            screenMeta.style.maxHeight = '0';\n            setTimeout(() => {\n                noticesPanel.style.display = '';\n                screenMeta.style.display = '';\n                screenMeta.style.transition = '';\n                screenMeta.style.overflow = '';\n                screenMeta.style.maxHeight = '';\n                this.toggleOtherScreenMetaTabs();\n            }, animationSeconds * 1000);\n        }\n\n    }\n\n    toggleOtherScreenMetaTabs() {\n        const otherTabs = document.querySelectorAll('#screen-meta-links .screen-meta-toggle:not(#ta-notices-link-wrap)');\n        otherTabs.forEach( (tab) => {\n            if (tab.style.visibility === 'hidden') {\n                tab.style.visibility = '';\n            } else {\n                tab.style.visibility = 'hidden';\n            }\n        } );\n    }\n}\n", "export default class ListTableShortcuts {\n\n    constructor() {\n        /**\n         * @type {ListTableShortcuts}\n         */\n        const me = this;\n\n        /**\n         * @type {null|HTMLElement}\n         */\n        this.currentRow = null;\n\n        /**\n         * @type {number}\n         */\n        this.currentRowIndex = 0;\n\n        /**\n         * @type {HTMLTableElement}\n         */\n        this.listTable = document.querySelector('.wp-list-table');\n\n        if (! this.listTable) {\n            return;\n        }\n\n        /**\n         * @type {NodeListOf<HTMLTableRowElement>}\n         */\n        this.tableRows = this.listTable.querySelectorAll('tbody#the-list > tr');\n\n        document.addEventListener('keyup', e => this.handleKeyup(e));\n    }\n\n    /**\n     *\n     * @param {KeyboardEvent} ev\n     */\n    handleKeyup(ev) {\n        if (document.activeElement.tagName !== 'BODY') {\n            return;\n        }\n\n        if (ev.key === 'j') {\n            this.tableMoveDown();\n        } else if (ev.key === 'k') {\n            this.tableMoveUp();\n        } else if (ev.key.toLowerCase() === 'enter' && this.currentRow !== null) {\n            this.openTableRowItem();\n        }\n\n    }\n\n    tableMoveDown() {\n        this.preTableChange();\n\n        // Move down\n        if (this.currentRow === null) {\n            this.currentRowIndex = 0;\n        } else {\n            this.currentRowIndex++;\n        }\n        this.updateTable();\n    }\n\n    tableMoveUp() {\n        this.preTableChange();\n\n        if (this.currentRowIndex > 0) {\n            this.currentRowIndex--;\n            this.updateTable();\n        }\n    }\n\n    preTableChange() {\n        if (this.currentRow !== null) {\n            this.tableRows[this.currentRowIndex].classList.remove('ta-active-table-row');\n        }\n    }\n\n    updateTable() {\n        this.currentRow = this.tableRows[this.currentRowIndex];\n\n        if (! this.tableRows[this.currentRowIndex].classList.contains('ta-active-table-row')) {\n            this.tableRows[this.currentRowIndex].classList.add('ta-active-table-row');\n        }\n    }\n\n    openTableRowItem() {\n        console.log(this);\n        /** @type {HTMLAnchorElement} */\n        const link = this.currentRow.querySelector('a.row-title');\n        if (link) {\n            link.click();\n        }\n    }\n}\n", "export default class TurboAdminBarkeeper {\n\n    constructor(barkeeperState) {\n        // Bail if we aren't in the admin\n        if (! document.getElementById('wpadminbar')) {\n            return;\n        }\n\n        this.exclusionIds = [\n            'wp-admin-bar-menu-toggle',\n            'wp-admin-bar-wp-logo',\n            'wp-admin-bar-site-name',\n            'wp-admin-bar-updates',\n        ];\n\n        this.barkeeperState = barkeeperState;\n\n        this.root = document.getElementById('wp-admin-bar-root-default');\n        this.itemsToHide = document.querySelectorAll( '#wp-admin-bar-root-default > li');\n\n        Array.from(this.itemsToHide).forEach( element => {\n            if (this.exclusionIds.includes(element.id)) {\n                return;\n            }\n            element.classList.add('ta-barkeeper-collapsable');\n        });\n\n        if (this.barkeeperState === 'closed') {\n            this.root.classList.toggle('ta-barkeeper-closed');\n        }\n\n        // Add toggle\n        this.button = document.createElement('button');\n        this.button.id = 'ta-barkeeper-toggle';\n        this.button.innerText = '<';\n\n        this.button.addEventListener('click', e => {\n            this.root.classList.toggle('ta-barkeeper-closed');\n\n            this.barkeeperState = this.barkeeperState === 'open' ? 'closed' : 'open';\n\n            if ('object' === typeof(browser)) {\n                browser.runtime.sendMessage({\n                    'action': 'barkeeperSetState',\n                    'barkeeperState': this.barkeeperState,\n                });\n            } else {\n                window.localStorage.setItem('turboAdminBarkeeperState', this.barkeeperState);\n            }\n        });\n\n        this.root.insertAdjacentElement('afterend', this.button);\n    }\n\n}\n", "/*\n * This is the common Turbo Admin library.\n *\n * It's (currently) WordPress-specific, but can be loaded by\n * either the Extension OR the Plugin\n *\n * It takes an options object:\n *\n * options: {\n *   shortcutKeys: [\n *     // Array of shortcut key definitions, like:\n *     {\n *       {\n *         meta: false,\n *         alt: true,\n *         ctrl: true,\n *         shift: true,\n *         key: 'p'\n *       }\n *     }\n *   ],\n *   appendToElement {\n *     // Optional CSS selector to define what to append the palette to\n *     'body'\n *   },\n *   extraItems: [\n *     // Optional array of extra item configs used to generate new item objects\n *     {\n *       'detectType': 'url',\n *       'detectPattern': 'wp-login',\n *       'itemTitle': 'View/visit site',\n *       'itemUrlFunction': () => this.home\n *     },\n *   ],\n *   extraItemsRaw: [\n *     // Optional array of raw item objects to be added\n *     {\n *       'title': ,\n *       'action': ,\n *       'parentTitle': ,\n *     }\n *   ]\n * }\n */\nimport TurboAdminPalette from './class-turbo-admin-palette.js';\nimport TurboAdminMenuItem from './class-turbo-admin-menu-item.js';\nimport Acf from './class-acf.js';\nimport TurboAdminWpBlockEditorFullscreenKill from './class-turbo-admin-wp-block-editor-fullscreen-kill.js';\nimport TurboAdminWpBlockEditorWelcomeGuideKill from './class-turbo-admin-wp-block-editor-welcome-guide-kill.js';\nimport TurboAdminWpNotices from './class-turbo-admin-wp-notices.js';\nimport TurboAdminListTableShortcuts from './class-list-table-shortcuts.js';\nimport TurboAdminBarkeeper from './class-turbo-admin-barkeeper.js';\n\nexport default class TurboAdmin {\n\n    constructor(options) {\n        if (document.getElementById('ta-command-palette-container')) {\n            console.log('TurboAdmin already initialised - I won\\'t make a second copy!');\n            return;\n        }\n\n        this.options = options;\n    }\n\n    async init() {\n        // Grab the global Wp object instance\n        this.wp = globalThis.taWp;\n\n        this.menu = [];\n        // Check for saved menu when on front-end\n        if (! this.wp.isBackend) {\n            // Only use the cached items if the current URL matches the last site URL\n            // This handles changes of multi-site site!\n            // We ONLY need to do this on the front-end as the back-end will always\n            // refresh the menu.\n            if (! this.wp.siteChanged) {\n                // Get from localStorage\n                const savedMenu = window.localStorage.getItem('ta-palette-data');\n\n                if (null !== savedMenu) {\n                    // Check for .logged-in class on body\n                    if (document.body.classList.contains('logged-in')) {\n                        // If still logged in merge (?) the items\n                        this.menu = JSON.parse(savedMenu);\n                    }\n                }\n            }\n        } else {\n            // On the back end, get the WordPress dashboard menu items\n            this.menu = this.getMenu();\n        }\n\n        // Add other additional items\n        this.addAdditionalMenuItems();\n        // Add items passed in using extraItemsRaw\n        this.menu = this.menu.concat(this.options.extraItemsRaw ?? []);\n\n        // Add ACF items?\n        // TODO: Make this better. Possible ASYNC somehow?\n        // this.acf = new Acf();\n        // if (this.acf.isAcfInstalled()) {\n        //     const acfLinks = await this.acf.getFieldGroups()\n        //     // console.table(acfItems);\n        //     const acfMenuItems = acfLinks.map(\n        //         item => new TurboAdminMenuItem(\n        //             item.label + ' (ACF)',\n        //             item.link,\n        //             ''\n        //         )\n        //     );\n        //     this.menu = this.menu.concat(acfMenuItems);\n        // }\n\n        // Sort the menu\n        this.menu.sort((a, b) => (a.parentTitle + a.title).localeCompare(b.parentTitle + b.title));\n\n        // Filter out no-cache items and save to localStorage.\n        const itemsToSave = this.menu.filter(item => (! item.noCache));\n        window.localStorage.setItem('ta-palette-data', JSON.stringify(itemsToSave));\n\n        // Add palette markup to the DOM\n        this.addPalette();\n        // Initialise controls on the palette\n        this.turboAdminPalette = new TurboAdminPalette(this.menu, this.options);\n\n        if (true === this.options['block-editor-fullscreen-disable']) {\n            // Initialise fullscreen kill\n            this.turboAdminFullscreenKill = new TurboAdminWpBlockEditorFullscreenKill();\n        }\n\n        if (true === this.options['block-editor-welcome-screen-kill']) {\n            this.turboAdminWelcomeKill = new TurboAdminWpBlockEditorWelcomeGuideKill();\n        }\n\n        if (true === this.options['list-table-keyboard-shortcuts']) {\n            this.turboAdminListTableShortcuts = new TurboAdminListTableShortcuts();\n        }\n\n        if (true === this.options['barkeeper']) {\n            // In the plugin, barkeeper-state will be in... local storage(?)\n            if ('object' !== typeof(browser)) {\n                this.options['barkeeper-state'] = window.localStorage.getItem('turboAdminBarkeeperState');\n            }\n            this.turboAdminBarkeeper = new TurboAdminBarkeeper(this.options['barkeeper-state']);\n        }\n\n        // Add other things if we're logged in and have an API nonce\n        if (globalThis.contentApi.userLoggedIn()) {\n            // What shall we do?\n        }\n    }\n\n    getMenu() {\n        const items = [];\n        const menuTop = document.getElementById('adminmenu');\n        if (menuTop) {\n            const topDOMItems = menuTop.querySelectorAll('li.menu-top');\n            topDOMItems.forEach(el => {\n                const a = el.querySelector('a.menu-top');\n                const title = a.querySelector('.wp-menu-name').innerHTML;\n                const action = a.href;\n                const parentTitle = '';\n                const item = new TurboAdminMenuItem(title, action, parentTitle);\n                items.push(item);\n\n                const subMenu = el.querySelector('.wp-submenu');\n                if (!subMenu) {\n                    return;\n                }\n                const subItems = subMenu.querySelectorAll('li a');\n                if (!subItems) {\n                    return;\n                }\n                subItems.forEach(subEl => {\n                    const parentTitle = title;\n                    const childTitle = subEl.innerHTML;\n                    const childAction = subEl.href;\n                    const item = new TurboAdminMenuItem(childTitle, childAction, parentTitle);\n                    items.push(item);\n                })\n            });\n        }\n        return items;\n    }\n\n    addAdditionalMenuItems() {\n\n        /*\n         * I'd LOVE for this to be config driven\n         *\n         * [\n         *   {\n         *     'detectType': 'url',\n         *     'detectPattern': 'wp-login',\n         *     'itemTitle': 'View/visit site',\n         *     'itemUrlFunction': () => this.home\n         *   },\n         *   {\n         *     'detectType': 'dom',\n         *     'detectSelector': '#wpadminbar',\n         *     'itemTitle': 'Logout',\n         *     'itemUrlFunction': () => logoutUrl\n         *   }\n         *  Can we add actionTypes as well? To do clicks and navigates?\n         * ]\n         */\n\n        // Get passed-in extraItems\n        let extraItems = this.options.extraItems ?? [];\n\n        // Merge in defaults\n        extraItems = extraItems.concat(\n            [\n                {\n                    'detectType': 'dom',\n                    'detectSelector': 'body.wp-admin #wp-admin-bar-view-site a',\n                    'itemTitleFunction': () => 'View/visit site',\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-dashboard a',\n                    'itemTitleFunction': (element) => element.textContent,\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wpadminbar',\n                    'itemTitleFunction': () => 'Logout',\n                    'itemUrlFunction': () => document.getElementById('wp-admin-bar-logout')?.querySelector('a')?.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-edit a',\n                    'itemTitleFunction': (item) => item.textContent,\n                    'itemUrlFunction': (item) => item.href,\n                    'noCache': true,\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-view a',\n                    'itemTitleFunction': (item) => item.textContent,\n                    'itemUrlFunction': (item) => item.href,\n                    'noCache': true,\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-new-content .ab-submenu a',\n                    'itemTitleFunction': (item) => 'New ' + item.textContent,\n                    'itemUrlFunction': (item) => item.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-customize a',\n                    'itemTitleFunction': (item) => item.textContent,\n                    'itemUrlFunction': (item) => item.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelectorNone': '#wpadminbar, #loginform',\n                    'itemTitleFunction': () => \"Log in\",\n                    'itemUrlFunction': () => {\n                        if (globalThis.taWp.home) {\n                            return globalThis.taWp.siteUrl;\n                        }\n                        // Try getting wp-admin\n                        return 'javascript:alert(\\'Sorry, could not detect login URL.\\')';\n                    }\n                },\n                // This is on the login screen\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#backtoblog a',\n                    'itemTitleFunction': () => \"View/visit site\",\n                    'itemUrlFunction': (element) => element.href\n                },\n                // Multisite items\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-network-admin > a',\n                    'itemTitleFunction': () => \"Network Admin\",\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-network-admin .ab-submenu a',\n                    'itemTitleFunction': (element) => 'Network Admin: ' + element.textContent,\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-my-sites-list .ab-submenu a',\n                    'itemTitleFunction': (element) => \"Sites: \" + element.closest('.menupop').querySelector('a').innerText + ' - ' + element.innerText,\n                    'itemUrlFunction': (element) => element.href\n                },\n                // Oxygen builder items\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#ct-edit-template-builder',\n                    'itemTitleFunction': () => 'Edit with Oxygen',\n                    'itemUrlFunction': (element) => element.href,\n                    'noCache': true\n                },\n                // It's worth noting that the Oxygen Builder doesn't use a /wp-admin URL\n                // and so kinda appears to Turbo Admin to be a \"front-end\" page and it\n                // doesn't refresh the menu items.\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '.oxygen-back-to-wp-menu .oxygen-toolbar-button-dropdown a:not(:last-of-type)',\n                    'itemTitleFunction': (element) => 'Back to WP: ' + element.textContent,\n                    'itemUrlFunction': (element) => {\n                        if (element.href) {\n                            return element.href;\n                        } else {\n                            let url = new URL(window.location.href);\n                            return url.origin + url.pathname;\n                        }\n                    },\n                    'noCache': true\n                }\n            ]\n        );\n\n        extraItems.forEach(item => {\n            let detected = false;\n            let elements = null;\n            if (item.detectType === 'url') {\n                detected = Boolean(window.location.href.includes(item.detectPattern));\n            } else if (item.detectType === 'dom') {\n                if (item.detectSelector) {\n                    elements = document.querySelectorAll(item.detectSelector);\n                    detected = Boolean(elements);\n                } else if (item.detectSelectorNone) {\n                    elements = document.querySelectorAll(item.detectSelectorNone);\n                    detected = elements.length === 0;\n                    // Need to pass SOMETHING to the loop below\n                    elements = document.querySelectorAll('body');\n                }\n            }\n            if (!detected) {\n                return;\n            }\n\n            elements.forEach(element => {\n                const newItem = new TurboAdminMenuItem(item.itemTitleFunction(element), item.itemUrlFunction(element), '', item?.noCache);\n                // Might already have one so check.\n                if (this.menu.some(menuItem => {\n                    // This must be newItem.sameAs, not menuItem.sameAs because the menuItem\n                    // may have been loaded from saved menu and may not actually be an instance\n                    // of a TurboAdminMenuItem.\n                    return newItem.sameAs(menuItem)\n                } )) {\n                    return;\n                }\n                // We don't already have one. So add it.\n                this.menu.push(newItem);\n            });\n        })\n    }\n\n    addPalette() {\n        const container = document.createElement('div');\n        container.id = 'ta-command-palette-container';\n        // Palette\n        const palette = document.createElement('div');\n        palette.id = 'ta-command-palette';\n        // Input field\n        const input = document.createElement('input');\n        input.id = \"ta-command-palette-input\";\n        input.name = \"ta-command-palette-input\";\n        input.type = \"text\";\n        // Set this to stop stuff trying to fill it.\n        input.setAttribute('autocomplete', 'off');\n        // List\n        const list = document.createElement('ul');\n        list.id = \"ta-command-palette-items\";\n        // Join it all up\n        container.appendChild(palette);\n        palette.appendChild(input);\n        palette.appendChild(list);\n\n        if (document.getElementById('wpadminbar') && this.options['admin-bar-search'] === true) {\n            const paletteLi = document.createElement('li');\n            paletteLi.appendChild(container);\n            const adminBar = document.getElementById('wp-admin-bar-top-secondary');\n            adminBar.appendChild(paletteLi);\n\n            // Add focus handler\n            input.addEventListener('focus', e => this.turboAdminPalette.showPalette());\n\n            // Add placeholder\n            const placeholder = document.createElement('div');\n            placeholder.id = 'ta-shortcut-key-placeholder';\n            placeholder.innerText = this.buildShortcutKeysString();\n            placeholder.addEventListener('click', e => input.focus());\n\n            palette.insertBefore( placeholder, list );\n        } else {\n            // Container\n            document.querySelector(this.options.appendToElement ?? 'body').appendChild(container);\n        }\n    }\n\n    buildShortcutKeysString () {\n        let keysString = '';\n        let shortcut = this.options.shortcutKeys[0];\n\n        if ( shortcut.meta ) {\n            keysString += 'Cmd-';\n        }\n        if ( shortcut.ctrl ) {\n            keysString += 'Ctrl-';\n        }\n        if ( shortcut.alt ) {\n            keysString += 'Alt-';\n        }\n        if ( shortcut.shift ) {\n            keysString += 'Shift-';\n        }\n        keysString += shortcut.key.toUpperCase();\n        return keysString;\n    }\n\n}\n", "export default class Wp {\n\n    constructor() {\n\n        // Set home and siteUrl\n        this.siteUrl = '';\n        this.home = '';\n        this.loginUrl = '';\n        this.apiLinkUrl = '';\n    }\n\n    async completeInit() {\n        // Fetch previously loaded site URL\n        this.previousUrl = window.localStorage.getItem('ta-palette-data-site');\n\n        // Fetch previously-stored siteUrl and home\n        this.siteUrl = window.localStorage.getItem('ta-palette-data-siteurl');\n        this.home = window.localStorage.getItem('ta-palette-data-home');\n\n        /**\n         * Are we in the back-end?\n         */\n        this.isBackend = this.getIsBackend();\n\n        /**\n         * Figure out all the WP URLs\n         */\n        await this.getUrls();\n\n        /**\n         * Tells you if the best-guess site URL of the current page is different\n         * to that of the previously saved site URL.\n         */\n        this.siteChanged = this.home !== this.previousUrl;\n\n        // Save current site URL for next time\n        window.localStorage.setItem('ta-palette-data-site', this.home);\n    }\n\n    getIsBackend() {\n        return document.body.classList.contains('wp-admin');\n    }\n\n    /**\n     * Return the URL with a trailing slash if it didn't already have one.\n     *\n     * @param {String} url The URL to check\n     * @return {String}    The resulting URL\n     */\n    ensureTrailingSlash( url ) {\n        if (url.endsWith('/')) {\n            return url;\n        } else {\n            return url + '/';\n        }\n    }\n\n    /**\n     * Tests if a URL works and, if redirected, that the final URL contains a given\n     * string. Returns the final, redirected-to URL if the test passed, or false\n     * otherwise.\n     *\n     * @param {String} url                    The URL to test.\n     * @param {String} responseUrlMustContain The string to test against the final URL\n     * @returns {Promise<String|Boolean>}   The final URL or false.\n     */\n    async testUrl(url, responseUrlMustContain='') {\n\n        /** @type {RequestInit} */\n        const init = {\n            method: 'HEAD',\n            mode: 'cors',\n            cache: 'no-cache',\n            credentials: 'same-origin'\n        }\n\n        const response = await fetch(url, init);\n\n        if (response.redirected && !response.url.includes(responseUrlMustContain)) {\n            return false;\n        }\n\n        if ( ! response.ok ) {\n            return false;\n        }\n\n        return response.url;\n    }\n\n    async findWhichUrlWorks(urls, responseUrlMustContain='') {\n        let workingUrl = false;\n        let result;\n        // This has to be a for loop rather than reduce or forEach as separate\n        // async callbacks would be launched asynchronously.\n        for (let i=0; i<urls.length; i++) {\n            if (workingUrl) continue;\n            result = await this.testUrl(urls[i], responseUrlMustContain);\n            if (result !== false) {\n                workingUrl = result;\n            }\n        }\n        return workingUrl;\n    }\n\n    /**\n     *\n     * @param {String} homeUrl\n     */\n    async guessSiteUrlFromHome( homeUrl ) {\n        const homeWithSlash = this.ensureTrailingSlash(homeUrl);\n\n        // NOTE: Backed out of this until I can make it work async.\n        // Might not even be a good idea anyway.\n\n        // const possibleUrls = [\n        //     homeWithSlash + 'wp-admin/',\n        //     homeWithSlash + 'wp/wp-admin'\n        // ];\n        // return this.findWhichUrlWorks(possibleUrls, 'wp-admin');\n        return homeWithSlash + 'wp-admin/';\n    }\n\n    /**\n     *\n     * @param {String} homeUrl\n     */\n    async guessHome() {\n        const currentUrl = new URL(window.location);\n        const origin = this.ensureTrailingSlash(currentUrl.origin);\n\n        // NOTE: Backed out of this until I can make it work async.\n        // Might not even be a good idea anyway.\n\n        // const possibleUrls = [\n        //     origin\n        // ];\n        // return this.findWhichUrlWorks(possibleUrls, 'wp-admin');\n        return origin;\n    }\n\n    /**\n     *\n     * @param {String} siteUrl\n     * @returns {String}\n     */\n    guessHomeFromSiteUrl(siteUrl) {\n        // Not much we can do here.\n        return siteUrl.replace(/wp-admin\\/?/, '');\n    }\n\n    async getUrls() {\n        // See if we can actually find the URL for the API\n        /** @type {HTMLLinkElement|null} */\n        const apiLink = document.querySelector('link[rel=\"https://api.w.org/\"]');\n\n        if (apiLink) {\n            this.apiLinkUrl = apiLink.href;\n        }\n        // Figure out the siteurl and home - this is different on the front and back end\n        if (this.isBackend) {\n            // This is easy in the back end/Dashboard!\n            this.siteUrl = window.location.href.match(/(^.*wp-admin)/)[1];\n            this.home = document.getElementById('wp-admin-bar-site-name').querySelector('a').href;\n\n            // Always set the siteUrl and home as this is definitive\n            window.localStorage.setItem('ta-palette-data-siteurl', this.siteUrl);\n            window.localStorage.setItem('ta-palette-data-home', this.home);\n        } else if (! this.siteUrl || ! this.home) {\n\n            // If we're not in the backend then (in the extension at least) we\n            // could be on the front-end and not logged in, so check for an\n            // admin bar and grab from that if there is one.\n            if (document.getElementById('wpadminbar')) {\n                this.siteUrl = document.getElementById('wp-admin-bar-dashboard').querySelector('a').href;\n                // Try for the API link\n                if (this.apiLinkUrl) {\n                    if (this.apiLinkUrl.includes('/wp-json')) {\n                        this.home = this.apiLinkUrl.replace('wp-json/', '');\n                    }\n                    if (this.apiLinkUrl.includes('index.php?rest_route')) {\n                        this.home = this.apiLinkUrl.replace(/index.php\\?rest_route.*/, '');\n                    }\n                } else {\n                    // We know what the siteUrl is, so guess the home from the siteUrl\n                    this.home = this.guessHomeFromSiteUrl(this.siteUrl);\n                }\n\n            } else {\n                // Try for the API link\n                // TODO: This needs to be async so it doesn't hold things up.\n                if (this.apiLinkUrl) {\n                    if (this.apiLinkUrl.includes('/wp-json')) {\n                        this.home = this.apiLinkUrl.replace('wp-json/', '');\n                    }\n                    if (this.apiLinkUrl.includes('index.php?rest_route')) {\n                        this.home = this.apiLinkUrl.replace(/index.php\\?rest_route.*/, '');\n                    }\n                    // We (probably) know what the home link is now, so guess the wp-admin\n                    if (this.home) {\n                        this.siteUrl = await this.guessSiteUrlFromHome( this.home );\n                    } else {\n                        this.siteUrl = this.guessSiteUrl();\n                    }\n                } else {\n                    // We got nothing.\n                    this.home    = await this.guessHome();\n                    if (this.home) {\n                        this.siteUrl = await this.guessSiteUrlFromHome(this.home);\n                    }\n                }\n            }\n        }\n\n        // Always trim the / for comparisons\n        if (this.siteUrl) {\n            this.siteUrl = this.siteUrl.replace(/(.+)\\/$/, '$1');\n        }\n        if (this.home) {\n            this.home = this.home.replace(/(.+)\\/$/, '$1');\n        }\n\n        // console.log('siteUrl: ', this.siteUrl);\n        // console.log('home: ', this.home);\n    }\n\n}\n", "import TurboAdmin from './class-turbo-admin.js';\nimport ContentApi from './class-content-api.js';\nimport Wp from './class-wp.js';\nimport TurboAdminWpNotices from './class-turbo-admin-wp-notices.js';\n\nconst taStorageKey = 'turbo-admin-settings';\n\n// Note that in the extension, the globalThis is not the browser's global scope,\n// it is sandboxed. So we can't check across the plugin/extension boundary here.\nasync function taInit(settings) {\n\n    globalThis.turboAdmin = null;\n\n    // Handle empty settings\n    if (typeof(settings[taStorageKey]) === 'undefined') {\n        console.log('Weird. Turbo Admin could not find any settings');\n        return;\n    }\n\n    globalThis.turboAdminOptions = settings[taStorageKey];\n\n    // Get Wp stuff ready\n    globalThis.taWp = new Wp();\n\n    // Parts of this init are async.\n    await globalThis.taWp.completeInit();\n\n    console.log('Turbo Admin: WP is initialised');\n\n    // Get/set api settings\n    globalThis.contentApi = new ContentApi();\n    await globalThis.contentApi.discoverApiRoot();\n\n    console.log('Turbo Admin: Content API is initialised');\n\n    globalThis.turboAdmin = new TurboAdmin(globalThis.turboAdminOptions);\n\n    await globalThis.turboAdmin.init();\n\n    if (settings[taStorageKey]['hide-notices']) {\n        globalThis.turboAdminWpNotices = new TurboAdminWpNotices(settings[taStorageKey].rememberedNoticeIds);\n    }\n}\n\n/**\n * This is plugin-specific. It should not be present in the extension code.\n */\ndocument.addEventListener('DOMContentLoaded', async e => {\n\tglobalThis.turboAdminOptions = {};\n\tglobalThis.turboAdminOptions[taStorageKey] = {\n\t\t// wpTurboAdmin is set using wp_localize_script\n\t\tshortcutKeys: globalThis.wpTurboAdmin.keys,\n        // These don't apply to the plugin version\n        'block-editor-fullscreen-disable': false,\n        'block-editor-welcome-screen-kill': false,\n        // I don't think we'll do this in the plugin as the code would be SO different.\n        'live-dev-notice': false,\n        'list-table-keyboard-shortcuts': globalThis.wpTurboAdmin['listTableShortcuts'] === '1',\n        'hide-notices': globalThis.wpTurboAdmin['hideNotices'] === '1',\n        'rememberedNoticeIds': JSON.parse(window.localStorage.getItem('rememberedNoticeIds')) ?? new Array(),\n        'barkeeper': globalThis.wpTurboAdmin['barkeeper'] === '1',\n        'admin-bar-search': globalThis.wpTurboAdmin['adminBarSearch'] === '1',\n\t}\n\tawait taInit(globalThis.turboAdminOptions);\n});\n"],
    5   "mappings": "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",
     3  "sources": ["../src/fuse-6.4.6.js", "../src/class-turbo-admin-palette.js", "../src/types/class-turbo-admin-menu-item.js", "../src/class-storage.js", "../src/apis/class-content-api.js", "../src/types/class-submenu-item.js", "../src/types/class-content-item.js", "../src/types/class-search-mode.js", "../src/types/class-item-definition.js", "../src/types/class-turbo-admin-plugin.js", "../src/class-turbo-admin-wp-notices.js", "../src/class-list-table-shortcuts.js", "../src/plugins/class-turbo-admin-barkeeper.js", "../src/plugins/class-turbo-admin-content-search.js", "../src/plugins/class-turbo-admin-plugins.js", "../src/plugins/class-turbo-admin-users.js", "../src/plugins/class-turbo-admin-mu-sites.js", "../src/plugins/class-turbo-admin-oxygen-buillder.js", "../src/class-turbo-admin.js", "../src/class-wp.js", "../src/apis/class-woocommerce-api.js", "../src/apis/class-gravity-forms-api.js", "../src/main.js"],
     4  "sourcesContent": ["/**\n * Fuse.js v6.4.6 - Lightweight fuzzy-search (http://fusejs.io)\n *\n * Copyright (c) 2021 Kiro Risk (http://kiro.me)\n * All Rights Reserved. Apache Software License 2.0\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\nvar e, t; e = this, t = function () { \"use strict\"; function e(t) { return (e = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (e) { return typeof e } : function (e) { return e && \"function\" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? \"symbol\" : typeof e })(t) } function t(e, t) { if (!(e instanceof t)) throw new TypeError(\"Cannot call a class as a function\") } function n(e, t) { for (var n = 0; n < t.length; n++) { var r = t[n]; r.enumerable = r.enumerable || !1, r.configurable = !0, \"value\" in r && (r.writable = !0), Object.defineProperty(e, r.key, r) } } function r(e, t, r) { return t && n(e.prototype, t), r && n(e, r), e } function i(e, t, n) { return t in e ? Object.defineProperty(e, t, { value: n, enumerable: !0, configurable: !0, writable: !0 }) : e[t] = n, e } function o(e, t) { var n = Object.keys(e); if (Object.getOwnPropertySymbols) { var r = Object.getOwnPropertySymbols(e); t && (r = r.filter((function (t) { return Object.getOwnPropertyDescriptor(e, t).enumerable }))), n.push.apply(n, r) } return n } function c(e) { for (var t = 1; t < arguments.length; t++) { var n = null != arguments[t] ? arguments[t] : {}; t % 2 ? o(Object(n), !0).forEach((function (t) { i(e, t, n[t]) })) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(n)) : o(Object(n)).forEach((function (t) { Object.defineProperty(e, t, Object.getOwnPropertyDescriptor(n, t)) })) } return e } function a(e, t) { if (\"function\" != typeof t && null !== t) throw new TypeError(\"Super expression must either be null or a function\"); e.prototype = Object.create(t && t.prototype, { constructor: { value: e, writable: !0, configurable: !0 } }), t && u(e, t) } function s(e) { return (s = Object.setPrototypeOf ? Object.getPrototypeOf : function (e) { return e.__proto__ || Object.getPrototypeOf(e) })(e) } function u(e, t) { return (u = Object.setPrototypeOf || function (e, t) { return e.__proto__ = t, e })(e, t) } function h(e, t) { return !t || \"object\" != typeof t && \"function\" != typeof t ? function (e) { if (void 0 === e) throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); return e }(e) : t } function f(e) { var t = function () { if (\"undefined\" == typeof Reflect || !Reflect.construct) return !1; if (Reflect.construct.sham) return !1; if (\"function\" == typeof Proxy) return !0; try { return Date.prototype.toString.call(Reflect.construct(Date, [], (function () { }))), !0 } catch (e) { return !1 } }(); return function () { var n, r = s(e); if (t) { var i = s(this).constructor; n = Reflect.construct(r, arguments, i) } else n = r.apply(this, arguments); return h(this, n) } } function l(e) { return function (e) { if (Array.isArray(e)) return d(e) }(e) || function (e) { if (\"undefined\" != typeof Symbol && Symbol.iterator in Object(e)) return Array.from(e) }(e) || function (e, t) { if (e) { if (\"string\" == typeof e) return d(e, t); var n = Object.prototype.toString.call(e).slice(8, -1); return \"Object\" === n && e.constructor && (n = e.constructor.name), \"Map\" === n || \"Set\" === n ? Array.from(e) : \"Arguments\" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n) ? d(e, t) : void 0 } }(e) || function () { throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\") }() } function d(e, t) { (null == t || t > e.length) && (t = e.length); for (var n = 0, r = new Array(t); n < t; n++)r[n] = e[n]; return r } function v(e) { return Array.isArray ? Array.isArray(e) : \"[object Array]\" === b(e) } function g(e) { return \"string\" == typeof e } function y(e) { return \"number\" == typeof e } function p(e) { return !0 === e || !1 === e || function (e) { return m(e) && null !== e }(e) && \"[object Boolean]\" == b(e) } function m(t) { return \"object\" === e(t) } function k(e) { return null != e } function M(e) { return !e.trim().length } function b(e) { return null == e ? void 0 === e ? \"[object Undefined]\" : \"[object Null]\" : Object.prototype.toString.call(e) } var x = function (e) { return \"Invalid value for key \".concat(e) }, L = function (e) { return \"Pattern length exceeds max of \".concat(e, \".\") }, S = Object.prototype.hasOwnProperty, w = function () { function e(n) { var r = this; t(this, e), this._keys = [], this._keyMap = {}; var i = 0; n.forEach((function (e) { var t = _(e); i += t.weight, r._keys.push(t), r._keyMap[t.id] = t, i += t.weight })), this._keys.forEach((function (e) { e.weight /= i })) } return r(e, [{ key: \"get\", value: function (e) { return this._keyMap[e] } }, { key: \"keys\", value: function () { return this._keys } }, { key: \"toJSON\", value: function () { return JSON.stringify(this._keys) } }]), e }(); function _(e) { var t = null, n = null, r = null, i = 1; if (g(e) || v(e)) r = e, t = O(e), n = j(e); else { if (!S.call(e, \"name\")) throw new Error(function (e) { return \"Missing \".concat(e, \" property in key\") }(\"name\")); var o = e.name; if (r = o, S.call(e, \"weight\") && (i = e.weight) <= 0) throw new Error(function (e) { return \"Property 'weight' in key '\".concat(e, \"' must be a positive integer\") }(o)); t = O(o), n = j(o) } return { path: t, id: n, weight: i, src: r } } function O(e) { return v(e) ? e : e.split(\".\") } function j(e) { return v(e) ? e.join(\".\") : e } var A = c({}, { isCaseSensitive: !1, includeScore: !1, keys: [], shouldSort: !0, sortFn: function (e, t) { return e.score === t.score ? e.idx < t.idx ? -1 : 1 : e.score < t.score ? -1 : 1 } }, {}, { includeMatches: !1, findAllMatches: !1, minMatchCharLength: 1 }, {}, { location: 0, threshold: .6, distance: 100 }, {}, { useExtendedSearch: !1, getFn: function (e, t) { var n = [], r = !1; return function e(t, i, o) { if (k(t)) if (i[o]) { var c = t[i[o]]; if (!k(c)) return; if (o === i.length - 1 && (g(c) || y(c) || p(c))) n.push(function (e) { return null == e ? \"\" : function (e) { if (\"string\" == typeof e) return e; var t = e + \"\"; return \"0\" == t && 1 / e == -1 / 0 ? \"-0\" : t }(e) }(c)); else if (v(c)) { r = !0; for (var a = 0, s = c.length; a < s; a += 1)e(c[a], i, o + 1) } else i.length && e(c, i, o + 1) } else n.push(t) }(e, g(t) ? t.split(\".\") : t, 0), r ? n : n[0] }, ignoreLocation: !1, ignoreFieldNorm: !1 }), I = /[^ ]+/g; function C() { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : 3, t = new Map, n = Math.pow(10, e); return { get: function (e) { var r = e.match(I).length; if (t.has(r)) return t.get(r); var i = 1 / Math.sqrt(r), o = parseFloat(Math.round(i * n) / n); return t.set(r, o), o }, clear: function () { t.clear() } } } var E = function () { function e() { var n = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}, r = n.getFn, i = void 0 === r ? A.getFn : r; t(this, e), this.norm = C(3), this.getFn = i, this.isCreated = !1, this.setIndexRecords() } return r(e, [{ key: \"setSources\", value: function () { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : []; this.docs = e } }, { key: \"setIndexRecords\", value: function () { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : []; this.records = e } }, { key: \"setKeys\", value: function () { var e = this, t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : []; this.keys = t, this._keysMap = {}, t.forEach((function (t, n) { e._keysMap[t.id] = n })) } }, { key: \"create\", value: function () { var e = this; !this.isCreated && this.docs.length && (this.isCreated = !0, g(this.docs[0]) ? this.docs.forEach((function (t, n) { e._addString(t, n) })) : this.docs.forEach((function (t, n) { e._addObject(t, n) })), this.norm.clear()) } }, { key: \"add\", value: function (e) { var t = this.size(); g(e) ? this._addString(e, t) : this._addObject(e, t) } }, { key: \"removeAt\", value: function (e) { this.records.splice(e, 1); for (var t = e, n = this.size(); t < n; t += 1)this.records[t].i -= 1 } }, { key: \"getValueForItemAtKeyId\", value: function (e, t) { return e[this._keysMap[t]] } }, { key: \"size\", value: function () { return this.records.length } }, { key: \"_addString\", value: function (e, t) { if (k(e) && !M(e)) { var n = { v: e, i: t, n: this.norm.get(e) }; this.records.push(n) } } }, { key: \"_addObject\", value: function (e, t) { var n = this, r = { i: t, $: {} }; this.keys.forEach((function (t, i) { var o = n.getFn(e, t.path); if (k(o)) if (v(o)) !function () { for (var e = [], t = [{ nestedArrIndex: -1, value: o }]; t.length;) { var c = t.pop(), a = c.nestedArrIndex, s = c.value; if (k(s)) if (g(s) && !M(s)) { var u = { v: s, i: a, n: n.norm.get(s) }; e.push(u) } else v(s) && s.forEach((function (e, n) { t.push({ nestedArrIndex: n, value: e }) })) } r.$[i] = e }(); else if (!M(o)) { var c = { v: o, n: n.norm.get(o) }; r.$[i] = c } })), this.records.push(r) } }, { key: \"toJSON\", value: function () { return { keys: this.keys, records: this.records } } }]), e }(); function $(e, t) { var n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, r = n.getFn, i = void 0 === r ? A.getFn : r, o = new E({ getFn: i }); return o.setKeys(e.map(_)), o.setSources(t), o.create(), o } function R(e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.errors, r = void 0 === n ? 0 : n, i = t.currentLocation, o = void 0 === i ? 0 : i, c = t.expectedLocation, a = void 0 === c ? 0 : c, s = t.distance, u = void 0 === s ? A.distance : s, h = t.ignoreLocation, f = void 0 === h ? A.ignoreLocation : h, l = r / e.length; if (f) return l; var d = Math.abs(a - o); return u ? l + d / u : d ? 1 : l } function F() { for (var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : [], t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : A.minMatchCharLength, n = [], r = -1, i = -1, o = 0, c = e.length; o < c; o += 1) { var a = e[o]; a && -1 === r ? r = o : a || -1 === r || ((i = o - 1) - r + 1 >= t && n.push([r, i]), r = -1) } return e[o - 1] && o - r >= t && n.push([r, o - 1]), n } function P(e) { for (var t = {}, n = 0, r = e.length; n < r; n += 1) { var i = e.charAt(n); t[i] = (t[i] || 0) | 1 << r - n - 1 } return t } var N = function () { function e(n) { var r = this, i = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, o = i.location, c = void 0 === o ? A.location : o, a = i.threshold, s = void 0 === a ? A.threshold : a, u = i.distance, h = void 0 === u ? A.distance : u, f = i.includeMatches, l = void 0 === f ? A.includeMatches : f, d = i.findAllMatches, v = void 0 === d ? A.findAllMatches : d, g = i.minMatchCharLength, y = void 0 === g ? A.minMatchCharLength : g, p = i.isCaseSensitive, m = void 0 === p ? A.isCaseSensitive : p, k = i.ignoreLocation, M = void 0 === k ? A.ignoreLocation : k; if (t(this, e), this.options = { location: c, threshold: s, distance: h, includeMatches: l, findAllMatches: v, minMatchCharLength: y, isCaseSensitive: m, ignoreLocation: M }, this.pattern = m ? n : n.toLowerCase(), this.chunks = [], this.pattern.length) { var b = function (e, t) { r.chunks.push({ pattern: e, alphabet: P(e), startIndex: t }) }, x = this.pattern.length; if (x > 32) { for (var L = 0, S = x % 32, w = x - S; L < w;)b(this.pattern.substr(L, 32), L), L += 32; if (S) { var _ = x - 32; b(this.pattern.substr(_), _) } } else b(this.pattern, 0) } } return r(e, [{ key: \"searchIn\", value: function (e) { var t = this.options, n = t.isCaseSensitive, r = t.includeMatches; if (n || (e = e.toLowerCase()), this.pattern === e) { var i = { isMatch: !0, score: 0 }; return r && (i.indices = [[0, e.length - 1]]), i } var o = this.options, c = o.location, a = o.distance, s = o.threshold, u = o.findAllMatches, h = o.minMatchCharLength, f = o.ignoreLocation, d = [], v = 0, g = !1; this.chunks.forEach((function (t) { var n = t.pattern, i = t.alphabet, o = t.startIndex, y = function (e, t, n) { var r = arguments.length > 3 && void 0 !== arguments[3] ? arguments[3] : {}, i = r.location, o = void 0 === i ? A.location : i, c = r.distance, a = void 0 === c ? A.distance : c, s = r.threshold, u = void 0 === s ? A.threshold : s, h = r.findAllMatches, f = void 0 === h ? A.findAllMatches : h, l = r.minMatchCharLength, d = void 0 === l ? A.minMatchCharLength : l, v = r.includeMatches, g = void 0 === v ? A.includeMatches : v, y = r.ignoreLocation, p = void 0 === y ? A.ignoreLocation : y; if (t.length > 32) throw new Error(L(32)); for (var m, k = t.length, M = e.length, b = Math.max(0, Math.min(o, M)), x = u, S = b, w = d > 1 || g, _ = w ? Array(M) : []; (m = e.indexOf(t, S)) > -1;) { var O = R(t, { currentLocation: m, expectedLocation: b, distance: a, ignoreLocation: p }); if (x = Math.min(O, x), S = m + k, w) for (var j = 0; j < k;)_[m + j] = 1, j += 1 } S = -1; for (var I = [], C = 1, E = k + M, $ = 1 << k - 1, P = 0; P < k; P += 1) { for (var N = 0, D = E; N < D;) { var z = R(t, { errors: P, currentLocation: b + D, expectedLocation: b, distance: a, ignoreLocation: p }); z <= x ? N = D : E = D, D = Math.floor((E - N) / 2 + N) } E = D; var K = Math.max(1, b - D + 1), q = f ? M : Math.min(b + D, M) + k, W = Array(q + 2); W[q + 1] = (1 << P) - 1; for (var J = q; J >= K; J -= 1) { var T = J - 1, U = n[e.charAt(T)]; if (w && (_[T] = +!!U), W[J] = (W[J + 1] << 1 | 1) & U, P && (W[J] |= (I[J + 1] | I[J]) << 1 | 1 | I[J + 1]), W[J] & $ && (C = R(t, { errors: P, currentLocation: T, expectedLocation: b, distance: a, ignoreLocation: p })) <= x) { if (x = C, (S = T) <= b) break; K = Math.max(1, 2 * b - S) } } var V = R(t, { errors: P + 1, currentLocation: b, expectedLocation: b, distance: a, ignoreLocation: p }); if (V > x) break; I = W } var B = { isMatch: S >= 0, score: Math.max(.001, C) }; if (w) { var G = F(_, d); G.length ? g && (B.indices = G) : B.isMatch = !1 } return B }(e, n, i, { location: c + o, distance: a, threshold: s, findAllMatches: u, minMatchCharLength: h, includeMatches: r, ignoreLocation: f }), p = y.isMatch, m = y.score, k = y.indices; p && (g = !0), v += m, p && k && (d = [].concat(l(d), l(k))) })); var y = { isMatch: g, score: g ? v / this.chunks.length : 1 }; return g && r && (y.indices = d), y } }]), e }(), D = function () { function e(n) { t(this, e), this.pattern = n } return r(e, [{ key: \"search\", value: function () { } }], [{ key: \"isMultiMatch\", value: function (e) { return z(e, this.multiRegex) } }, { key: \"isSingleMatch\", value: function (e) { return z(e, this.singleRegex) } }]), e }(); function z(e, t) { var n = e.match(t); return n ? n[1] : null } var K = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = e === this.pattern; return { isMatch: t, score: t ? 0 : 1, indices: [0, this.pattern.length - 1] } } }], [{ key: \"type\", get: function () { return \"exact\" } }, { key: \"multiRegex\", get: function () { return /^=\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^=(.*)$/ } }]), i }(D), q = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = -1 === e.indexOf(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"inverse-exact\" } }, { key: \"multiRegex\", get: function () { return /^!\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^!(.*)$/ } }]), i }(D), W = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = e.startsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, this.pattern.length - 1] } } }], [{ key: \"type\", get: function () { return \"prefix-exact\" } }, { key: \"multiRegex\", get: function () { return /^\\^\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^\\^(.*)$/ } }]), i }(D), J = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = !e.startsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"inverse-prefix-exact\" } }, { key: \"multiRegex\", get: function () { return /^!\\^\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^!\\^(.*)$/ } }]), i }(D), T = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = e.endsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [e.length - this.pattern.length, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"suffix-exact\" } }, { key: \"multiRegex\", get: function () { return /^\"(.*)\"\\$$/ } }, { key: \"singleRegex\", get: function () { return /^(.*)\\$$/ } }]), i }(D), U = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { var t = !e.endsWith(this.pattern); return { isMatch: t, score: t ? 0 : 1, indices: [0, e.length - 1] } } }], [{ key: \"type\", get: function () { return \"inverse-suffix-exact\" } }, { key: \"multiRegex\", get: function () { return /^!\"(.*)\"\\$$/ } }, { key: \"singleRegex\", get: function () { return /^!(.*)\\$$/ } }]), i }(D), V = function (e) { a(i, e); var n = f(i); function i(e) { var r, o = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, c = o.location, a = void 0 === c ? A.location : c, s = o.threshold, u = void 0 === s ? A.threshold : s, h = o.distance, f = void 0 === h ? A.distance : h, l = o.includeMatches, d = void 0 === l ? A.includeMatches : l, v = o.findAllMatches, g = void 0 === v ? A.findAllMatches : v, y = o.minMatchCharLength, p = void 0 === y ? A.minMatchCharLength : y, m = o.isCaseSensitive, k = void 0 === m ? A.isCaseSensitive : m, M = o.ignoreLocation, b = void 0 === M ? A.ignoreLocation : M; return t(this, i), (r = n.call(this, e))._bitapSearch = new N(e, { location: a, threshold: u, distance: f, includeMatches: d, findAllMatches: g, minMatchCharLength: p, isCaseSensitive: k, ignoreLocation: b }), r } return r(i, [{ key: \"search\", value: function (e) { return this._bitapSearch.searchIn(e) } }], [{ key: \"type\", get: function () { return \"fuzzy\" } }, { key: \"multiRegex\", get: function () { return /^\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^(.*)$/ } }]), i }(D), B = function (e) { a(i, e); var n = f(i); function i(e) { return t(this, i), n.call(this, e) } return r(i, [{ key: \"search\", value: function (e) { for (var t, n = 0, r = [], i = this.pattern.length; (t = e.indexOf(this.pattern, n)) > -1;)n = t + i, r.push([t, n - 1]); var o = !!r.length; return { isMatch: o, score: o ? 0 : 1, indices: r } } }], [{ key: \"type\", get: function () { return \"include\" } }, { key: \"multiRegex\", get: function () { return /^'\"(.*)\"$/ } }, { key: \"singleRegex\", get: function () { return /^'(.*)$/ } }]), i }(D), G = [K, B, W, J, U, T, q, V], H = G.length, Q = / +(?=([^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)/; function X(e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}; return e.split(\"|\").map((function (e) { for (var n = e.trim().split(Q).filter((function (e) { return e && !!e.trim() })), r = [], i = 0, o = n.length; i < o; i += 1) { for (var c = n[i], a = !1, s = -1; !a && ++s < H;) { var u = G[s], h = u.isMultiMatch(c); h && (r.push(new u(h, t)), a = !0) } if (!a) for (s = -1; ++s < H;) { var f = G[s], l = f.isSingleMatch(c); if (l) { r.push(new f(l, t)); break } } } return r })) } var Y = new Set([V.type, B.type]), Z = function () { function e(n) { var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, i = r.isCaseSensitive, o = void 0 === i ? A.isCaseSensitive : i, c = r.includeMatches, a = void 0 === c ? A.includeMatches : c, s = r.minMatchCharLength, u = void 0 === s ? A.minMatchCharLength : s, h = r.ignoreLocation, f = void 0 === h ? A.ignoreLocation : h, l = r.findAllMatches, d = void 0 === l ? A.findAllMatches : l, v = r.location, g = void 0 === v ? A.location : v, y = r.threshold, p = void 0 === y ? A.threshold : y, m = r.distance, k = void 0 === m ? A.distance : m; t(this, e), this.query = null, this.options = { isCaseSensitive: o, includeMatches: a, minMatchCharLength: u, findAllMatches: d, ignoreLocation: f, location: g, threshold: p, distance: k }, this.pattern = o ? n : n.toLowerCase(), this.query = X(this.pattern, this.options) } return r(e, [{ key: \"searchIn\", value: function (e) { var t = this.query; if (!t) return { isMatch: !1, score: 1 }; var n = this.options, r = n.includeMatches; e = n.isCaseSensitive ? e : e.toLowerCase(); for (var i = 0, o = [], c = 0, a = 0, s = t.length; a < s; a += 1) { var u = t[a]; o.length = 0, i = 0; for (var h = 0, f = u.length; h < f; h += 1) { var d = u[h], v = d.search(e), g = v.isMatch, y = v.indices, p = v.score; if (!g) { c = 0, i = 0, o.length = 0; break } if (i += 1, c += p, r) { var m = d.constructor.type; Y.has(m) ? o = [].concat(l(o), l(y)) : o.push(y) } } if (i) { var k = { isMatch: !0, score: c / i }; return r && (k.indices = o), k } } return { isMatch: !1, score: 1 } } }], [{ key: \"condition\", value: function (e, t) { return t.useExtendedSearch } }]), e }(), ee = []; function te(e, t) { for (var n = 0, r = ee.length; n < r; n += 1) { var i = ee[n]; if (i.condition(e, t)) return new i(e, t) } return new N(e, t) } var ne = \"$and\", re = \"$or\", ie = \"$path\", oe = \"$val\", ce = function (e) { return !(!e[ne] && !e[re]) }, ae = function (e) { return !!e[ie] }, se = function (e) { return !v(e) && m(e) && !ce(e) }, ue = function (e) { return i({}, ne, Object.keys(e).map((function (t) { return i({}, t, e[t]) }))) }; function he(e, t) { var n = t.ignoreFieldNorm, r = void 0 === n ? A.ignoreFieldNorm : n; e.forEach((function (e) { var t = 1; e.matches.forEach((function (e) { var n = e.key, i = e.norm, o = e.score, c = n ? n.weight : null; t *= Math.pow(0 === o && c ? Number.EPSILON : o, (c || 1) * (r ? 1 : i)) })), e.score = t })) } function fe(e, t) { var n = e.matches; t.matches = [], k(n) && n.forEach((function (e) { if (k(e.indices) && e.indices.length) { var n = { indices: e.indices, value: e.value }; e.key && (n.key = e.key.src), e.idx > -1 && (n.refIndex = e.idx), t.matches.push(n) } })) } function le(e, t) { t.score = e.score } function de(e, t) { var n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, r = n.includeMatches, i = void 0 === r ? A.includeMatches : r, o = n.includeScore, c = void 0 === o ? A.includeScore : o, a = []; return i && a.push(fe), c && a.push(le), e.map((function (e) { var n = e.idx, r = { item: t[n], refIndex: n }; return a.length && a.forEach((function (t) { t(e, r) })), r })) } var ve = function () { function e(n) { var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, i = arguments.length > 2 ? arguments[2] : void 0; t(this, e), this.options = c({}, A, {}, r), this.options.useExtendedSearch, this._keyStore = new w(this.options.keys), this.setCollection(n, i) } return r(e, [{ key: \"setCollection\", value: function (e, t) { if (this._docs = e, t && !(t instanceof E)) throw new Error(\"Incorrect 'index' type\"); this._myIndex = t || $(this.options.keys, this._docs, { getFn: this.options.getFn }) } }, { key: \"add\", value: function (e) { k(e) && (this._docs.push(e), this._myIndex.add(e)) } }, { key: \"remove\", value: function () { for (var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : function () { return !1 }, t = [], n = 0, r = this._docs.length; n < r; n += 1) { var i = this._docs[n]; e(i, n) && (this.removeAt(n), n -= 1, r -= 1, t.push(i)) } return t } }, { key: \"removeAt\", value: function (e) { this._docs.splice(e, 1), this._myIndex.removeAt(e) } }, { key: \"getIndex\", value: function () { return this._myIndex } }, { key: \"search\", value: function (e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.limit, r = void 0 === n ? -1 : n, i = this.options, o = i.includeMatches, c = i.includeScore, a = i.shouldSort, s = i.sortFn, u = i.ignoreFieldNorm, h = g(e) ? g(this._docs[0]) ? this._searchStringList(e) : this._searchObjectList(e) : this._searchLogical(e); return he(h, { ignoreFieldNorm: u }), a && h.sort(s), y(r) && r > -1 && (h = h.slice(0, r)), de(h, this._docs, { includeMatches: o, includeScore: c }) } }, { key: \"_searchStringList\", value: function (e) { var t = te(e, this.options), n = this._myIndex.records, r = []; return n.forEach((function (e) { var n = e.v, i = e.i, o = e.n; if (k(n)) { var c = t.searchIn(n), a = c.isMatch, s = c.score, u = c.indices; a && r.push({ item: n, idx: i, matches: [{ score: s, value: n, norm: o, indices: u }] }) } })), r } }, { key: \"_searchLogical\", value: function (e) { var t = this, n = function (e, t) { var n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, r = n.auto, i = void 0 === r || r, o = function e(n) { var r = Object.keys(n), o = ae(n); if (!o && r.length > 1 && !ce(n)) return e(ue(n)); if (se(n)) { var c = o ? n[ie] : r[0], a = o ? n[oe] : n[c]; if (!g(a)) throw new Error(x(c)); var s = { keyId: j(c), pattern: a }; return i && (s.searcher = te(a, t)), s } var u = { children: [], operator: r[0] }; return r.forEach((function (t) { var r = n[t]; v(r) && r.forEach((function (t) { u.children.push(e(t)) })) })), u }; return ce(e) || (e = ue(e)), o(e) }(e, this.options), r = this._myIndex.records, i = {}, o = []; return r.forEach((function (e) { var r = e.$, c = e.i; if (k(r)) { var a = function e(n, r, i) { if (!n.children) { var o = n.keyId, c = n.searcher, a = t._findMatches({ key: t._keyStore.get(o), value: t._myIndex.getValueForItemAtKeyId(r, o), searcher: c }); return a && a.length ? [{ idx: i, item: r, matches: a }] : [] } switch (n.operator) { case ne: for (var s = [], u = 0, h = n.children.length; u < h; u += 1) { var f = e(n.children[u], r, i); if (!f.length) return []; s.push.apply(s, l(f)) } return s; case re: for (var d = [], v = 0, g = n.children.length; v < g; v += 1) { var y = e(n.children[v], r, i); if (y.length) { d.push.apply(d, l(y)); break } } return d } }(n, r, c); a.length && (i[c] || (i[c] = { idx: c, item: r, matches: [] }, o.push(i[c])), a.forEach((function (e) { var t, n = e.matches; (t = i[c].matches).push.apply(t, l(n)) }))) } })), o } }, { key: \"_searchObjectList\", value: function (e) { var t = this, n = te(e, this.options), r = this._myIndex, i = r.keys, o = r.records, c = []; return o.forEach((function (e) { var r = e.$, o = e.i; if (k(r)) { var a = []; i.forEach((function (e, i) { a.push.apply(a, l(t._findMatches({ key: e, value: r[i], searcher: n }))) })), a.length && c.push({ idx: o, item: r, matches: a }) } })), c } }, { key: \"_findMatches\", value: function (e) { var t = e.key, n = e.value, r = e.searcher; if (!k(n)) return []; var i = []; if (v(n)) n.forEach((function (e) { var n = e.v, o = e.i, c = e.n; if (k(n)) { var a = r.searchIn(n), s = a.isMatch, u = a.score, h = a.indices; s && i.push({ score: u, key: t, value: n, idx: o, norm: c, indices: h }) } })); else { var o = n.v, c = n.n, a = r.searchIn(o), s = a.isMatch, u = a.score, h = a.indices; s && i.push({ score: u, key: t, value: o, norm: c, indices: h }) } return i } }]), e }(); return ve.version = \"6.4.6\", ve.createIndex = $, ve.parseIndex = function (e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = t.getFn, r = void 0 === n ? A.getFn : n, i = e.keys, o = e.records, c = new E({ getFn: r }); return c.setKeys(i), c.setIndexRecords(o), c }, ve.config = A, function () { ee.push.apply(ee, arguments) }(Z), ve }, \"object\" == typeof exports && \"undefined\" != typeof module ? module.exports = t() : \"function\" == typeof define && define.amd ? define(t) : (e = e || self).Fuse = t();\n", "/*\n * Some notes on how this works...\n *\n * paletteData is passed into the constructor and is the initial list of items\n * these are TurboAdminMenuItem objects\n *\n * At any point, buildPaletteItems() can be called to turn the paletteData\n * into an array of \"li\" nodes.\n *\n * updatePaletteItems inserts the paletteItems into the \"ul\" list and sets the\n * selectedElement\n *\n * The selectedItem is always one of the paletteItems\n *\n * paletteSearch rebuilds the paletteItems from the paletteData using\n * buildPaletteItems, and then filters the list with FuseJS\n */\n\nimport Fuse from './fuse-6.4.6.js';\nimport TurboAdminMenuItem from './types/class-turbo-admin-menu-item';\nimport ContentApi from './apis/class-content-api.js';\nimport SearchMode from './types/class-search-mode.js';\nimport ContentItem from './types/class-content-item.js';\n\nexport default class TurboAdminPalette {\n\n\tconstructor(paletteData, options) {\n\n\t\tconsole.log('Initialising TurboAdmin');\n\n        this.options = options;\n\n        /** @type {HTMLDivElement} */\n        this.paletteElement      = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-container'));\n        /** @type {HTMLDivElement} */\n        this.paletteInnerElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette'));\n\t\t/** @type {HTMLInputElement} */\n        this.paletteInputElement = /** @type {HTMLInputElement} */ (document.getElementById('ta-command-palette-input'));\n\t\t/** @type {HTMLDivElement} */\n        this.paletteItemsContainerElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-items-container'));\n\t\t/** @type {HTMLUListElement} */\n        this.paletteItemsElement = /** @type {HTMLUListElement} */ (document.getElementById('ta-command-palette-items'));\n\t\t/** @type {HTMLDivElement} */\n        this.paletteSubmenuContainerElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-submenu-container'));\n        /** @type {HTMLDivElement} */\n        this.paletteSearchModeTag = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-search-mode-tag'));\n        /** @type {HTMLDivElement} */\n        this.paletteSearchModeTabNotice = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-tab-notice'));\n        /** @type {HTMLSpanElement} */\n        this.paletteSearchModeTabNoticeText = /** @type {HTMLSpanElement} */ (document.getElementById('ta-command-palette-tab-notice-text'));\n        /** @type {HTMLDivElement} */\n        this.paletteNoticeElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-notice'));\n\n\n        // Add a class if the menu needs refreshing with a visit to the Dashboard\n        if (globalThis.turboAdmin.menuNeedsRefresh) {\n            this.showPaletteNotice('Menu needs refreshing. Visit the Dashboard to refresh.');\n        }\n\n        // We need this when injecting items. We use it to help generate edit URLs. Not the best way but\n        // works for now.\n        /** @type {HTMLUListElement} */\n        this.profileLinkElem = document.getElementById('wp-admin-bar-edit-profile');\n        /** @type {null|String} */\n        this.profileLink = null;\n        if (this.profileLinkElem) {\n            this.profileLink = this.profileLinkElem.querySelector('a').href;\n        }\n\n\t\t// Get palette data\n\t\tthis.paletteData = paletteData;\n\n        // Backup of the palette data for use when we enter a different search mode\n\t\tthis.paletteDataBackup = null;\n\t\tthis.paletteItemsBackup = null;\n        this.paletteItemIndexBackup = null;\n\n        // Current search modes/keyword\n        this.searchMode = null;\n\n        // paletteItems is the list of 'li' elements used to build the palette\n        this.paletteItems = [];\n\n        // itemIndex is a \"cache\" of URLs used to check if we already\n        // have an item in the palette\n        this.itemIndex = {};\n\n        // Convert into LI elements\n        this.buildPaletteItems();\n\n\n\t\tthis.selectedItem = this.paletteItems[0];\n        this.openedSubMenu = null;\n        this.selectedSubItem = null;\n\n\t\t// Add them to the DOM\n\t\tthis.updatePaletteItems();\n\n        // Set state\n        this.navigating = false;\n        this.debounceTimeout;\n\n\t\tthis.paletteFuseOptions = [];\n\t\tthis.paletteFuse = null;\n\n\t\tif (typeof (Fuse) !== 'function') {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.paletteFuseOptions = {\n\t\t\tkeys: ['innerText'],\n\t\t}\n\n\t\tthis.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);\n\n\t\tdocument.addEventListener('keydown', e => this.handleGlobalKey(e));\n\n\t\tthis.paletteElement.addEventListener('click', e => {\n\t\t\tthis.checkForPaletteItemClick(e);\n            this.checkForClickToClose(e);\n\t\t});\n\n        this.paletteItemsElement.addEventListener('mouseover', e => {\n            this.setHoveredItem(e.target);\n        });\n\t}\n\n    htmlDecode(input) {\n        var doc = new DOMParser().parseFromString(input, \"text/html\");\n        return doc.documentElement.textContent;\n    }\n\n    isMac() {\n        return navigator.platform.startsWith('Mac');\n    }\n\n    metaPressed(e) {\n        return this.isMac() ? e.metaKey : e.ctrlKey;\n    }\n\n    inSearchMode() {\n        return this.searchMode !== null;\n    }\n\n\t/**\n     * This converts this.paletteData into a list of paletteListItems in this.paletteItems\n     *\n     * It also builds the itemIndex\n     */\n    buildPaletteItems() {\n        this.paletteItems = [];\n        this.itemIndex = {};\n\n\t\tthis.paletteData.forEach(item => {\n\t\t\tconst li = document.createElement('li');\n\t\t\tconst a = document.createElement('a');\n\t\t\tli.appendChild(a);\n\t\t\ta.href = item.action;\n\t\t\tlet title = item.title;\n\t\t\tif (item.parentTitle) {\n\t\t\t\ttitle = item.parentTitle + \": \" + title;\n\t\t\t}\n\t\t\ta.innerHTML = title;\n            this.addPaletteListItem(li);\n\t\t});\n\t}\n\n    // This takes a 'li' element and adds it to the paletteItems.\n    // It also updates any caches and stuff.\n    addPaletteListItem(listItem) {\n        this.paletteItems.push(listItem);\n\n        const link = listItem.querySelector('a');\n        if (link) {\n            this.itemIndex[link.href] = 1;\n        }\n    }\n\n    contentItemExists(url) {\n        return Boolean(this.itemIndex[url]);\n    }\n\n    /**\n     * Clears and sets the content items\n     *\n     * @param {ContentItem[]} contentItems\n     */\n    setContentItems(contentItems) {\n        this.paletteItems = [];\n        this.itemIndex = [];\n        this.injectContentItems(contentItems, false);\n    }\n\n    /**\n     * Content items have:\n     *  title\n     *  subtype\n     *  url\n     *  (we should also make the sub-menu definable, but that's not done yet)\n     *\n     * @param {ContentItem[]} contentItems\n     */\n    injectContentItems(contentItems, andRunSearch = true) {\n        console.log('Injecting items');\n\n        if (contentItems.length > 0) {\n            contentItems.forEach(this.injectItem.bind(this));\n        }\n\n        if (andRunSearch) {\n            // Reset the search to work on the new items\n            this.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);\n            this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map(i => i.item);\n        }\n\n        this.updatePaletteItems();\n    }\n\n    /**\n     * Injects a single content item into the palette\n     *\n     * @param {ContentItem} item\n     */\n    injectItem(item) {\n        const itemTitle = item.title;\n        // const itemTitle = item.title.rendered;\n        const itemType = item.subtype;\n        const itemUrl = item.url;\n\n        // console.log('Adding item: ' + itemTitle);\n\n        // // Check if item already exists\n        if (this.contentItemExists(itemUrl)) {\n            console.log('Not adding duplicate');\n            return;\n        }\n\n        let title = itemTitle;\n\n        if (itemType) {\n            const itemTypeName = globalThis.contentApi.postTypes[itemType] ? globalThis.contentApi.postTypes[itemType].name : itemType;\n            title += ` (${itemTypeName})`;\n        }\n\n        const li = document.createElement('li');\n        const a = document.createElement('a');\n        let subMenu = null;\n\n        // Loop over submenu items OR add link.\n        if (item.submenuItems.length > 0) {\n\n            // Prepare the outer sub-menu elements\n            subMenu = document.createElement('div');\n            const subMenuTitle = document.createElement('div');\n            const subMenuItems = document.createElement('ul');\n            subMenu.classList.add('ta-submenu');\n            subMenuTitle.classList.add('ta-submenu-title');\n\n            subMenuTitle.textContent = this.htmlDecode(itemTitle);\n            subMenuItems.classList.add('ta-submenu-items');\n            subMenu.appendChild(subMenuTitle);\n\n            for (let i = 0; i < item.submenuItems.length; i++) {\n                const subMenuItem = item.submenuItems[i]\n                // TODO: Abstract this so sub-menus can be defined by plugins?\n                const subMenuListItem = document.createElement('li');\n                const subMenuLink = document.createElement('a');\n                subMenuLink.innerText = subMenuItem.title;\n                subMenuLink.href = subMenuItem.url;\n                for (let a = 0; a < subMenuItem.attributes.length; a++) {\n                    subMenuLink.setAttribute(\n                        subMenuItem.attributes[a].name,\n                        subMenuItem.attributes[a].value\n                    )\n                }\n                subMenuListItem.appendChild(subMenuLink);\n                subMenuItems.appendChild(subMenuListItem);\n            }\n\n            // Add the sub-menu items UL to the sub-menu element.\n            subMenu.appendChild(subMenuItems);\n\n            li.classList.add('ta-has-child-menu');\n        }\n\n        a.href = itemUrl;\n        a.innerHTML = title;\n\n        li.appendChild(a);\n        if (subMenu !== null) {\n            li.appendChild(subMenu);\n        }\n\n        this.addPaletteListItem(li);\n    }\n\n\t/**\n     * Handle global keypresses (at document level). Note that other key presses\n     * are handled by paletteActions()\n     *\n     * @param {KeyboardEvent} e\n     */\n    async handleGlobalKey(e) {\n\t\tif (this.shortcutKeysPressed(e)) {\n            e.preventDefault();\n            e.stopPropagation();\n\t\t\tif (this.paletteShown()) {\n\t\t\t\tthis.hidePalette();\n\t\t\t} else {\n\t\t\t\tthis.showPalette();\n\t\t\t}\n            return;\n\t\t}\n\n\t\tif (e.code === 'Escape' && this.paletteShown()) {\n\t\t\tif (this.isSubMenuOpen()){\n                this.closeSubMenu();\n            } else if (this.inSearchMode()) {\n                this.leaveSearchMode();\n            } else {\n                this.hidePalette();\n            }\n            return;\n\t\t}\n\n        if (this.paletteShown()) {\n            await this.paletteActions(e);\n\t\t}\n\t}\n\n\tshortcutKeysPressed(keyEvent) {\n        // The reduce here works through all the different possible key combos\n        // (more than one can be specified in options)\n\t\tconst keysPressed = this.options.shortcutKeys.reduce(\n\t\t\t(keyPressed, combo) => {\n\t\t\t\tif (keyPressed) {\n\t\t\t\t\treturn keyPressed;\n\t\t\t\t}\n                return ((!navigator.platform.startsWith('Mac')) || (combo.meta === keyEvent.metaKey))\n                    && (combo.alt === keyEvent.altKey)\n                    && (combo.shift === keyEvent.shiftKey)\n                    && (combo.ctrl === keyEvent.ctrlKey)\n                    && (\n                        keyEvent.code === 'Key' + combo.key.toUpperCase()\n                        || ( combo.key === ' ' && keyEvent.code.toUpperCase() === 'SPACE' )\n                    );\n            }, false);\n\t\treturn keysPressed;\n\t}\n\n    /*\n     * Adds the tab hint for a keyword once it has been typed.\n     */\n    maybeHighlightInputKeyword(newKey) {\n        // Do nothing if we are in a search-mode\n        if (this.inSearchMode()) {\n            return;\n        }\n\n        // This is fired on \"keyDown\", so the value isn't update with the new key yet.\n        // But don't do this for special keys, and catch backspace too.\n        let newInputValue = this.paletteInputElement.value;\n        if (newKey.length === 1) {\n            newInputValue += newKey;\n        }\n        if (newKey === 'Backspace') {\n            newInputValue = newInputValue.slice(0, -1);\n        }\n        // console.log(`Checking palette input value ${newInputValue} for keyword`);\n        if (this.isKeyword(newInputValue)) {\n            this.paletteSearchModeTabNoticeText.innerText = `Search for ${newInputValue}`;\n            this.paletteSearchModeTabNotice.classList.add('active');\n        } else {\n            this.unhighlightInputKeyword();\n        }\n    }\n\n    unhighlightInputKeyword() {\n        this.paletteSearchModeTabNotice.classList.remove('active');\n    }\n\n    async debouncedPaletteSearchAndUpdate() {\n        // If we're not in a search mode then search immediately\n        if (! this.inSearchMode()) {\n            this.debounceTimeout = null;\n            await this.paletteSearchAndUpdate();\n            return;\n        }\n\n        // If timer is null, reset it to 500ms and run your functions.\n        // Otherwise, wait until timer is cleared\n\n        // Cancel the existing timeout\n        clearTimeout(this.debounceTimeout)\n\n        this.debounceTimeout = setTimeout(async function () {\n            // Reset timeout\n            this.debounceTimeout = null;\n\n            // Run the search function\n            await this.paletteSearchAndUpdate();\n        }.bind(this), 750);\n    }\n\n    /**\n     * Check if a string is a search mode keyword\n     *\n     * @param {string} inputString\n     * @returns {boolean}\n     */\n    isKeyword(inputString) {\n        return Object.keys(globalThis.turboAdmin.searchModes).includes(inputString);\n    }\n\n    /**\n     * Show the palette notice with the specified text\n     *\n     * @param {string} text\n     */\n    showPaletteNotice(text) {\n        this.paletteNoticeElement.classList.add('active');\n        this.paletteNoticeElement.innerText = text;\n    }\n\n    /**\n     * Hide the palette notice\n     */\n    hidePaletteNotice() {\n        this.paletteNoticeElement.classList.remove('active');\n    }\n\n\t/**\n     * Handle (non-global) keypresses on the palette\n     *\n     * @param {KeyboardEvent} e\n     * @returns {Promise}\n     */\n    async paletteActions(e) {\n\t\tif (e.code === 'ArrowDown' && this.paletteShown()) {\n\t\t\te.preventDefault();\n\t\t\tthis.moveDown();\n\t\t\treturn;\n\t\t}\n\t\tif (e.code === 'ArrowUp' && this.paletteShown()) {\n\t\t\te.preventDefault();\n\t\t\tthis.moveUp();\n\t\t\treturn;\n\t\t}\n\t\tif (e.code === 'Enter' && this.paletteShown()) {\n            e.preventDefault();\n            this.doAction(this.metaPressed(e));\n            return;\n\t\t}\n\n        /*\n         * Only the actions above can be done in sub-menus.\n         */\n        if (this.isSubMenuOpen()) {\n            return;\n        }\n\n        /*\n         * Check for a keyword being typed and add a UI hint.\n         */\n        this.maybeHighlightInputKeyword(e.key);\n\n        /*\n         * Tabbing looks for a search mode keyword.\n         */\n        if (! this.inSearchMode() && (e.code === 'Tab' || e.key === ':')) {\n            console.log('Checking for search mode');\n            let inputValue = this.paletteInputElement.value;\n            if (this.isKeyword(inputValue)) {\n                console.log('Found search mode ' + inputValue)\n                e.preventDefault();\n                // TODO: Work on this.\n                await this.enterSearchMode(\n                    globalThis.turboAdmin.searchModes[inputValue]);\n                return;\n            }\n        }\n\n        /*\n         * Backspace may exit us from a search mode\n         */\n        if (this.inSearchMode() && e.code === 'Backspace' && this.paletteInputElement.value === '') {\n            e.preventDefault();\n            this.leaveSearchMode();\n            return;\n        }\n\n\t\tawait this.debouncedPaletteSearchAndUpdate();\n\t}\n\n    /**\n     * Puts the palette into a specific search mode - used when a keyword is selected\n     *\n     * @param {SearchMode} searchMode\n     */\n    async enterSearchMode(searchMode) {\n        console.log('Entering search mode for keyword ' + searchMode.keyword);\n        this.backupPaletteData();\n\n        this.paletteData = [];\n        this.paletteItems = [];\n        this.itemIndex = [];\n\n        // Remove the notice if it's there\n        this.hidePaletteNotice();\n\n        this.searchMode = searchMode;\n        this.paletteInputElement.value = '';\n        this.addSearchModeTag(searchMode.displayName);\n        this.unhighlightInputKeyword();\n        this.updatePaletteItems();\n        // This is similar to code in paletteSearch - maybe we could extract/abstract it?\n        if (searchMode.defaultItemsCallback !== null) {\n            this.paletteInnerElement.classList.add('loading');\n            const results = await searchMode.defaultItemsCallback();\n            this.setContentItems(results);\n            // this.injectContentItems(results);\n            this.paletteInnerElement.classList.remove('loading');\n        }\n    }\n\n    /**\n     * Leaves the current search mode\n     */\n    leaveSearchMode() {\n        const searchMode = this.searchMode;\n        // It's important what we set this to - see inSearchMode()\n        this.searchMode = null;\n        this.removeSearchModeTag();\n        this.restorePaletteData();\n        this.paletteInputElement.value = searchMode.keyword;\n        this.maybeHighlightInputKeyword('');\n        this.paletteSearchAndUpdate();\n    }\n\n    /**\n     * Backups up the palette data to a local variable so that it can be\n     * restored later.\n     */\n    backupPaletteData() {\n        this.paletteDataBackup = this.paletteData;\n        this.paletteItemsBackup = this.paletteItems;\n        this.paletteItemIndexBackup = this.itemIndex;\n    }\n\n    /**\n     * Restores the save palette data - does not rebuild anything\n     */\n    restorePaletteData() {\n        this.paletteData = this.paletteDataBackup;\n        this.paletteItems = this.paletteItemsBackup;\n        this.itemIndex = this.paletteItemIndexBackup;\n    }\n\n    /**\n     * Adds the search mode tag with the specified title.\n     *\n     * @param {string} title\n     */\n    addSearchModeTag(title) {\n        this.paletteSearchModeTag.classList.add('active');\n        this.paletteSearchModeTag.innerText = title;\n    }\n\n    /**\n     * Removes the search mode tag\n     */\n    removeSearchModeTag() {\n        this.paletteSearchModeTag.classList.remove('active');\n    }\n\n    isPaletteOpen() {\n        return this.paletteElement?.classList.contains('active');\n    }\n\n\tshowPalette() {\n        // Bail if already shown (this can be triggered by a focus event)\n        if (this.isPaletteOpen()) {\n            return;\n        }\n\n        this.paletteInputElement.value = '';\n\t\tthis.paletteInputElement?.focus();\n\t\tthis.paletteElement?.classList.add('active');\n        // This is needed in admin-bar mode otherwise it gets a weird already-scrolled thing when\n        // the palette opens.\n        setTimeout(() => this.paletteItemsElement.scrollTop = 0, 100);\n\t}\n\n\thidePalette() {\n        this.navigating = false;\n\t\tthis.paletteElement?.classList.remove('active');\n        this.paletteInputElement.value = '';\n        this.paletteInputElement.blur();\n        if (this.isSubMenuOpen()) {\n            this.closeSubMenu();\n        }\n        if (this.searchMode !== null) {\n            this.leaveSearchMode();\n        }\n\t}\n\n\tpaletteShown() {\n\t\treturn this.paletteElement?.classList.contains('active');\n\t}\n\n    checkForPaletteItemClick(e) {\n        if (e.target.tagName === 'A') {\n            e.preventDefault();\n            if (this.isSubMenuOpen()) {\n                this.selectedSubItem = e.target.closest('li');\n            } else {\n                this.selectedItem = e.target.closest('li');\n            }\n            this.setSelectedElement();\n\n            this.doAction(this.metaPressed(e));\n        }\n    }\n\n\tcheckForClickToClose(e) {\n\t\tif (e.target.id === this.paletteElement.id) {\n\t\t\tthis.hidePalette();\n\t\t}\n\t}\n\n\tsetSelectedElement() {\n        if (this.isSubMenuOpen()) {\n            this.paletteSubmenuContainerElement?.querySelectorAll('.ta-submenu li.selected')?.forEach(e => e.classList.remove('selected'));\n            this.selectedSubItem.classList.add('selected');\n        } else {\n            this.paletteItemsElement?.querySelectorAll('li.selected')?.forEach(e => e.classList.remove('selected'));\n            if (this.selectedItem) {\n                this.selectedItem.classList.add('selected');\n                this.scrollList();\n            }\n        }\n\t}\n\n\tscrollList() {\n\t\t// Scrolling up\n\t\tif (this.selectedItem.offsetTop < this.paletteItemsElement.scrollTop) {\n\t\t\tthis.paletteItemsElement.scrollTop = this.selectedItem.offsetTop;\n\t\t}\n\t\t// Scrolling down\n\t\tif (this.selectedItem.offsetTop + this.selectedItem.offsetHeight > this.paletteItemsElement.offsetHeight + this.paletteItemsElement.scrollTop) {\n\t\t\tthis.paletteItemsElement.scrollTop = this.selectedItem.offsetTop + this.selectedItem.offsetHeight - this.paletteItemsElement.offsetHeight;\n\t\t}\n\t}\n\n    setHoveredItem(element) {\n        // Only do this for li's\n        if ('LI' === element.tagName) {\n            this.navigating = true;\n            if (this.isSubMenuOpen()) {\n                this.selectedSubItem = element;\n            } else {\n                this.selectedItem = element;\n            }\n            this.setSelectedElement();\n        }\n    }\n\n\tmoveDown() {\n        if (this.isSubMenuOpen()) {\n            const nextItem = this.selectedSubItem.nextElementSibling;\n            this.navigating = true;\n            if (nextItem) {\n                this.selectedSubItem = nextItem;\n                this.setSelectedElement();\n            }\n        } else {\n            const nextItem = this.selectedItem.nextElementSibling;\n            this.navigating = true;\n            if (nextItem) {\n                this.selectedItem = nextItem;\n                this.setSelectedElement();\n            }\n        }\n\t}\n\n\tmoveUp() {\n        if (this.isSubMenuOpen()) {\n            const prevItem = this.selectedSubItem.previousElementSibling;\n            this.navigating = true;\n            if (prevItem) {\n                this.selectedSubItem = prevItem;\n                this.setSelectedElement();\n            }\n        } else {\n            const prevItem = this.selectedItem.previousElementSibling;\n            this.navigating = true;\n            if (prevItem) {\n                this.selectedItem = prevItem;\n                this.setSelectedElement();\n            }\n        }\n    }\n\n    isSubMenuOpen() {\n        return null !== this.openedSubMenu;\n    }\n\n    openSubMenu(subMenuElement) {\n        this.paletteSubmenuContainerElement.replaceChildren(subMenuElement);\n        // Set height in case main menu is smaller than sub menu\n        const subMenuHeight = this.paletteSubmenuContainerElement.offsetHeight;\n        this.paletteItemsContainerElement.style.minHeight = subMenuHeight + \"px\";\n        this.paletteSubmenuContainerElement.classList.add('active');\n\n        this.selectedSubItem = subMenuElement.querySelector('li');\n        this.openedSubMenu = subMenuElement;\n        this.setSelectedElement();\n\n        this.paletteInputElement.disabled = true;\n        // Blur the input so that keys can continue to be captured\n        this.paletteInputElement.blur();\n    }\n\n    closeSubMenu(subMenuElement = null) {\n        if (null === subMenuElement) {\n            subMenuElement = document.querySelector('.ta-submenu.active');\n        }\n        this.paletteSubmenuContainerElement.classList.remove('active');\n        this.selectedSubItem.classList.remove('active');\n        this.paletteItemsContainerElement.style.minHeight = 'auto';\n        this.selectedSubItem = null;\n        this.openedSubMenu = null;\n        this.paletteInputElement.disabled = false;\n        this.paletteInputElement.focus();\n    }\n\n\tdoAction(metaPressed = false) {\n        if (this.isSubMenuOpen()) {\n            this.actOnItem(this.selectedSubItem, metaPressed);\n            return;\n        }\n        if (this.selectedItem.classList.contains('ta-has-child-menu')) {\n            const subMenu = this.selectedItem.querySelector('.ta-submenu');\n            this.openSubMenu(subMenu);\n            return;\n        }\n\n        this.actOnItem(this.selectedItem, metaPressed);\n    }\n\n    actOnItem(item, metaPressed) {\n        this.hidePalette();\n        const link = item.querySelector('a');\n        const url = link.href;\n\n        // link.href will be interpolated by the browser, so if it's empty it will be the current page\n        // use getAttribute instead to work out if its empty\n        if (link.getAttribute('href') === '') {\n            return;\n        }\n\n        if ('clipboard' === link.dataset.action) {\n            navigator.clipboard.writeText(url);\n            return;\n        }\n\n        if (metaPressed) {\n            window.open(url, '_blank');\n        } else {\n            window.location = url;\n        }\n    }\n\n\tselectedItemDisplayed() {\n\t\treturn Array.from(this.paletteItemsElement.childNodes).includes(this.selectedItem);\n\t}\n\n\tasync paletteSearchAndUpdate() {\n\t\tawait this.paletteSearch();\n\t\tthis.updatePaletteItems();\n\t}\n\n\tasync paletteSearch() {\n        // Get the value...\n        // const response = await globalThis.contentApi.get('posts', { search: this.paletteInputElement.value, per_page: 100, status: ['publish', 'future', 'draft', 'pending', 'private'] });\n\n        if (! this.searchMode) {\n            this.buildPaletteItems();\n\n            if (this.paletteInputElement.value !== '') {\n                // Reset the search to work on the new items\n                this.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);\n                this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map(i => i.item);\n            }\n            return;\n        }\n\n        if (this.paletteInputElement.value.length === 0) {\n            this.paletteInnerElement.classList.add('loading');\n            let results = [];\n            if (this.searchMode.defaultItemsCallback !== null) {\n                results = await this.searchMode.defaultItemsCallback();\n            }\n            this.setContentItems(results);\n            // this.injectContentItems(results);\n            this.paletteInnerElement.classList.remove('loading');\n        } else {\n            // This is copied to enterSearchMode. Should probably be extracted.\n            this.paletteInnerElement.classList.add('loading');\n            const results = await this.searchMode.searchCallback(this.paletteInputElement.value);\n            this.setContentItems(results);\n            // this.injectContentItems(results);\n            this.paletteInnerElement.classList.remove('loading');\n        }\n\n        /**\n         * OLD CODE BELOW\n         */\n        // Content search - don't search everything!\n        // if (globalThis.contentApi.active && this.postTypes !== [] && this.paletteInputElement.value.length > 2) {\n        //     this.paletteInnerElement.classList.add('loading');\n\n        //     globalThis.contentApi.getPosts(this.paletteInputElement.value)\n        //         .then(\n        //             results => {\n        //                     this.injectContentItems(results);\n        //                     this.paletteInnerElement.classList.remove('loading');\n        //             }\n        //         )\n        // }\n\t}\n\n\tupdatePaletteItems() {\n\t\tconst newItems = document.createElement('ul');\n\t\tnewItems.id = 'ta-command-palette-items';\n\n\t\tthis.paletteItems.forEach(i => {\n\t\t\tnewItems.appendChild(i);\n\t\t})\n\n\t\tthis.paletteItemsElement.replaceChildren(...newItems.children);\n\n\t\tif (!this.navigating || !this.selectedItemDisplayed()) {\n\t\t\tthis.selectedItem = this.paletteItems[0];\n\t\t}\n\n\t\tthis.setSelectedElement();\n\t}\n\n}\n", "/**\n * Menu items are the items ready to appear in the palette.\n *\n * These are standard items, not content items. Though this should probably be standardised.\n */\nexport default class TurboAdminMenuItem {\n\n    /**\n     * The title of the item\n     *\n     * @type {string}\n     */\n    title = '';\n\n    /**\n     * The action of the item is the URL to visit when the item is clicked\n     *\n     * @type {string}\n     */\n    action = '';\n\n    /**\n     * The parent title is the title of the parent item under which the current item\n     * was found in the WordPress menu.\n     *\n     * e.g. in Posts -> Add Post, \"Posts\" is the parent item.\n     *\n     * @type {string}\n     */\n    parentTitle = '';\n\n    /**\n     * True if the item is not to be cached. Used for things like post-specific links like \"Edit post\"\n     *\n     * @type {boolean}\n     */\n    noCache = false;\n\n\tconstructor(title, action, parentTitle, noCache = false) {\n\t\tthis.title = title;\n\t\tthis.action = action;\n\t\tthis.parentTitle = parentTitle;\n        this.noCache = noCache;\n\t}\n\n    sameAs(item) {\n        return item.title === this.title &&\n            item.action === this.action &&\n            item.parentTitle === this.parentTitle;\n    }\n}\n", "/**\n * This class is an abstraction of the browser extension storage API\n * (see https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage)\n * but that falls back to using regular localStorage if we're not in a\n * browser extension.\n *\n * This exists so that the same API can be used from both the browser\n * extension AND the plugin version of Turbo Admin.\n *\n * Note that for the extension, data saved is \"global\" to the extension\n * and is NOT site specific.\n */\nexport default class Storage {\n\n    /**\n     * Constructor - detects where code is running and sets the local\n     * store appropriately.\n     */\n    constructor() {\n        /** @type {null|storageStorageArea|WindowLocalStorage} */\n        this.store = null;\n\n        if ('undefined' === typeof (browser)) {\n            this.store = window.localStorage;\n        } else {\n            this.store = browser.storage.local;\n        }\n    }\n\n    /**\n     * Set/save extension data. Must be passed an object with key/value\n     * pairs.\n     *\n     * @param {Object} dataObject\n     */\n    async set(dataObject) {\n        if ('undefined' === typeof (browser)) {\n            const keys = Object.keys(dataObject);\n            keys.forEach(key => this.store.setItem(key, JSON.stringify(dataObject[key])));\n        } else {\n            await this.store.set(dataObject);\n        }\n    }\n\n    /**\n     * Get data from the extension's storage.\n     *\n     * Note that fetched data will be a object with the key as a\n     * property.\n     *\n     * @param {String} key\n     * @returns {Promise<Object>}\n     */\n    async get(key) {\n        if ('undefined' === typeof (browser)) {\n            let returnObj = {};\n            let item = this.store.getItem(key);\n            if (! item) {\n                return returnObj;\n            }\n            let itemObject = null;\n            try {\n                itemObject = JSON.parse(this.store.getItem(key));\n            } catch (e) {\n                itemObject = null;\n            }\n            returnObj[key] = itemObject;\n            return returnObj;\n        } else {\n            return await this.store.get(key);\n        }\n    }\n\n}\n", "import Storage from '../class-storage.js';\n\nexport default class ContentApi {\n\n    constructor() {\n        // this.discoverApiRoot().then(e => null);\n        // console.log('Discovered API base: ', this.apiBase);\n        this.active = false;\n        this.store = new Storage();\n        this.postTypes = [];\n\n        // This is used to \"cache\" duplicate requests.\n        // It's an object because it will have search strings as keys\n        this.cache = {};\n    }\n\n    async discoverApiRoot() {\n        console.log('Discovering API root');\n        let wpApiSettings = null;\n        this.storageKey = 'wpApiSettings.' + globalThis.taWp.home;\n\n        // Could be in the wp-api-request-js-extra (on wp-admin side)\n        const wpApiSettingsScript = document.getElementById('wp-api-request-js-extra');\n        if (wpApiSettingsScript) {\n            const wpApiSettingsString = wpApiSettingsScript.innerHTML.match(/var\\s+wpApiSettings\\s+=\\s+(.+);/)[1];\n            const wpApiSettings = JSON.parse(wpApiSettingsString);\n            const objectToSave = {};\n            objectToSave[this.storageKey] = wpApiSettings;\n            await this.store.set(objectToSave);\n            this.apiRoot = wpApiSettings.root;\n            this.apiBase = this.apiRoot + wpApiSettings.versionString;\n            this.apiNonce = wpApiSettings.nonce;\n            // Clear the nonce if one is set and we're not logged in\n            this.maybeExpireNonce(wpApiSettings);\n            this.active = true;\n            return;\n        }\n\n        // Getting from extension storage returns a object with the key\n        // as the key. Which is weird.\n        wpApiSettings = await this.store.get(this.storageKey);\n        if (wpApiSettings\n            && Object.keys(wpApiSettings).length !== 0\n            && wpApiSettings[this.storageKey]\n            && 'object' === typeof(wpApiSettings[this.storageKey])) {\n            // Get the key'ed item out of the object\n            wpApiSettings = wpApiSettings[this.storageKey];\n            this.apiRoot = wpApiSettings.root;\n            this.apiBase = this.apiRoot + wpApiSettings.versionString;\n            this.apiNonce = wpApiSettings.nonce;\n            // Clear the nonce if one is set and we're not logged in\n            this.maybeExpireNonce(wpApiSettings);\n            this.active = true;\n            return;\n        }\n\n        // Could be in <link rel=\"https://api.w.org/\" href=\"https://something/wp-json/\">\n        if (globalThis.taWp.apiLinkUrl) {\n            this.apiRoot = globalThis.taWp.apiLinkUrl;\n            // Just guess this\n            this.apiBase = this.apiRoot + 'wp/v2/';\n            this.active = true;\n            return;\n        }\n        // This should be very rare. I should only really see it in development.\n        console.log('API Route Discovery failed');\n        // TODO: This can't display as the palette isn't created yet.\n        // globalThis.turboAdmin.turboAdminPalette.showPaletteNotice('Can\\'t find the WP API. Try visiting the dashboard to refresh things.');\n    }\n\n    async discoverPostTypes() {\n        console.log('Discovering post types');\n        if (! this.active) {\n            console.log('Not active');\n            this.postTypes = [];\n            return;\n        }\n\n        this.postTypes = await this.getPostTypes();\n        console.log('Discovered post types: ', this.postTypes);\n    }\n\n    userLoggedIn() {\n        return document.body.classList.contains('logged-in') ||\n            document.body.classList.contains('wp-admin');\n    }\n\n    async maybeExpireNonce(wpApiSettings) {\n        if (wpApiSettings?.nonce && ! this.userLoggedIn()) {\n            // Clear apiSetting nonce\n            this.apiNonce = null;\n            wpApiSettings.nonce = null;\n            const objectToSave = {};\n            objectToSave[this.storageKey] = wpApiSettings;\n            await this.store.set(objectToSave);\n        }\n    }\n\n    makeParamString(data) {\n        const params = new URLSearchParams();\n\n        Object.keys(data).forEach(paramKey => {\n            // Handle arrays\n            if (Array.isArray(data[paramKey])) {\n                const arrayParamKey = paramKey + '[]';\n                data[paramKey].forEach( item => params.append(arrayParamKey, item));\n            } else {\n                params.append(paramKey, data[paramKey]);\n            }\n        });\n\n        return params.toString();\n    }\n\n    statuses() {\n        if (this.apiNonce) {\n            return [\"publish\", \"future\", \"draft\", \"pending\", \"private\"];\n        } else {\n            return [\"publish\"];\n        }\n    }\n\n    async getPostTypes() {\n        // Check the cache\n        if (undefined !== this.cache['postsTypes']) {\n            return this.cache['postTypes'];\n        }\n\n        // Fetch results\n        const response = await this.get('types');\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['postTypes'] = result;\n\n        return result;\n    }\n\n    async getPosts(searchString, postType = 'any') {\n        // Check the cache\n        const cacheKey =  `posts-${postType}-${searchString}`;\n        if (undefined !== this.cache[cacheKey]) {\n            return this.cache[cacheKey];\n        }\n\n        // Fetch results\n        const response = await this.get(\n            // \"posts\",\n            \"search\",\n            {\n                search: searchString,\n                per_page: 100,\n                // status: this.statuses(),\n                type: 'post',\n                subtype: postType\n            }\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache[cacheKey] = result;\n\n        return result;\n    }\n\n    /**\n     * We can't use the API to get a post of any post type. So we hack this a bit.\n     *\n     * @param {number} postId\n     * @returns {Promise<any>}\n     */\n    async doesPostExist(postId) {\n        // Check the cache\n        if (undefined !== this.cache['post-' + postId]) {\n            return this.cache['post-' + postId];\n        }\n\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n            credentials: 'include'\n        }\n\n        const response = await fetch(`${globalThis.taWp.siteUrl}/post.php?post=${postId}&action=edit`, init);\n\n        this.cache['post-' + postId] = response;\n\n        return response?.status === 200;\n    }\n\n    async getPlugins(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['plugins-' + searchString]) {\n            return this.cache['plugins-' + searchString];\n        }\n\n        let requestOptions = {};\n\n        if (searchString) {\n            requestOptions.search = searchString;\n        }\n\n        // Fetch results\n        const response = await this.get(\n            \"plugins\",\n            requestOptions\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['plugins-' + searchString] = result;\n\n        return result;\n    }\n\n    async getUsers(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['users-' + searchString]) {\n            return this.cache['users-' + searchString];\n        }\n\n        // Fetch results\n        const response = await this.get(\n            \"users\",\n            {\n                search: searchString,\n                per_page: 100,\n                context: 'edit' // view / embed / edit\n            }\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['users-' + searchString] = result;\n\n        return result;\n    }\n\n    async get(path, data = {}) {\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n            credentials: 'include'\n        }\n\n        // Add the nonce if there is one\n        if (this.apiNonce) {\n            data._wpnonce = this.apiNonce;\n        }\n\n        const params = this.makeParamString(data);\n\n        const response = await fetch(`${this.apiBase}${path}/?${params}`, init);\n\n        if (response.status < 200 || response.status >= 300) {\n            globalThis.turboAdmin.turboAdminPalette.showPaletteNotice('WordPress API Error. Try visiting the dashboard to refresh things.');\n        }\n\n        return response;\n    }\n\n}\n", "export default class SubmenuItem {\n    /**\n     * The title of the item\n     *\n     * @type {string}\n     */\n    title;\n\n    /**\n     * The URL of the item\n     * @type {string}\n     */\n    url;\n\n    /**\n     * A list of attributes to go on the A tag (not the LI tag)\n     *\n     * @type {array}\n     */\n    attributes = [];\n\n    /**\n     * Create a submenu item\n     *\n     * @param {string} title The title of the item\n     * @param {string} url The URL of the item\n     */\n    constructor(title, url) {\n        this.title = title;\n        this.url = url;\n    }\n\n    /**\n     * Add an attribute\n     *\n     * @param {string} name The attribute name\n     * @param {string} value The attribute value\n     */\n    addAttribute(name, value) {\n        this.attributes.push({\n            name: name,\n            value: value\n        });\n    }\n}\n", "import SubmenuItem from \"./class-submenu-item\";\n\nexport default class ContentItem {\n    /**\n     * The title of the item\n     *\n     * @type {string}\n     */\n    title = '';\n\n    /**\n     * The subtype of the item. e.g. for posts, this will be the post type.\n     * Used to display extra information about the item.\n     *\n     * @type {string}\n     */\n    subtype = '';\n\n    /**\n     * The URL of the item. Leave empty if there is a sub-menu.\n     *\n     * @type {string}\n     */\n    url = '';\n\n    /**\n     * The sub-menu items, if any.\n     *\n     * This should be an empty array if the item itself has a URL\n     *\n     * @type {SubmenuItem[]}\n     */\n    submenuItems = [];\n}\n", "import ContentItem from \"./class-content-item\";\n\nexport default class SearchMode {\n    /**\n     * The keyword string used to initiate the search\n     *\n     * @type {string}\n     */\n    keyword = '';\n\n    /**\n     * The dispay name used for the search\n     *\n     * @type {string}\n     */\n    displayName = '';\n\n    /**\n     * jsDoc defintion for a `searchCallback`\n     *\n     * @callback SearchCallback\n     * @param {string} [searchString]\n     * @returns {Promise<ContentItem[]>}\n     */\n\n    /**\n     * Callback to get search items\n     *\n     * @type {SearchCallback}\n     */\n    searchCallback;\n\n    /**\n     * Callback to get default items when entering a search mode\n     *\n     * @type {SearchCallback|null}\n     */\n    defaultItemsCallback = null;\n\n    /**\n     * Constructs a new search mode\n     *\n     * @param {string} keyword\n     * @param {string} displayName\n     * @param {SearchCallback} searchCallback\n     * @param {SearchCallback} defaultItemsCallback\n     */\n    constructor(keyword, displayName, searchCallback, defaultItemsCallback = null) {\n        this.keyword = keyword;\n        this.displayName = displayName;\n        this.searchCallback = searchCallback;\n        this.defaultItemsCallback = defaultItemsCallback;\n    }\n}\n", "/**\n * An item definition specifies how to detect a palette item from the Dashboard's Dom\n *\n * These are all processed on initialisation to generate menu items.\n *\n * Note that a single definition may generate multiple menu items if the selectors used\n * discover multiple items.\n */\nexport default class ItemDefinition {\n    /**\n     * This callback is displayed as part of the Requester class.\n    * @callback menuItemCallback\n    * @param {HTMLElement} element\n    * @returns {string}\n    */\n\n    /**\n     * The method of detecting items. Can be:\n     *  - 'dom' for checking if a DOM element exists (requires detectSelector or detectSelectorNone)\n     *  - 'url' if the current URL is being checked (requires detectPattern)\n     *\n     * @type {string}\n     */\n    detectType = 'dom';\n\n    /**\n     * [OPTIONAL] A CSS selector used to find items in the DOM\n     *\n     * @type {string}\n     */\n    detectSelector = '';\n\n    /**\n     * [OPTIONAL] A CSS selector used to check for an absence of items in the DOM\n     *\n     * @type {string}\n     */\n    detectSelectorNone = '';\n\n    /**\n     * A callback used to generate a menu item title from a detected element. Should be passed an\n     * HTML element and should return a string\n     *\n     * @type {menuItemCallback|null}\n     */\n     itemTitleFunction = null;\n\n    /**\n     * A callback used to generate a menu item link URL from a detected element. Should be passed an\n     * HTML element and should return a string\n     *\n     * @type {menuItemCallback|null}\n     */\n     itemUrlFunction = null;\n\n     /**\n      * True if the item is not to be cached. Used for things like post-specific links like \"Edit post\"\n      *\n      * @type {boolean}\n      */\n     noCache = false;\n}\n", "import SearchMode from \"./class-search-mode\";\nimport ItemDefinition from \"./class-item-definition\";\n\n/**\n * This is an abstract class that should be extended by plugins\n * @module TurboAdminPlugin\n */\nexport default class TurboAdminPlugin {\n    /** @type {string} */\n    name = '';\n\n    /** @type {SearchMode[]} */\n    searchModes = [];\n\n    /** @type {boolean} */\n    activated = false;\n\n    constructor(pluginName) {\n        this.name = pluginName;\n        this.registerPlugin();\n    }\n\n    /**\n     * Register the plugin with Turbo Admin\n     */\n    registerPlugin() {\n        console.log('Inside plugin - requested registration of ' + this.name);\n        globalThis.turboAdmin.registerPlugin(this);\n    }\n\n    /**\n     * Returns true if the plugin should activate\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        return false;\n    }\n\n    /**\n     * Activates the plugin\n     * @return {void}\n     */\n    activate() {\n        this.activated = true;\n        this.registerSearchModes();\n    }\n\n    /**\n     * Register the search keywords with Turbo Admin - each will be registered\n     * with the whole plugin object.\n     */\n    registerSearchModes() {\n        this.searchModes.forEach(globalThis.turboAdmin.registerSearchMode);\n    }\n\n    /**\n     * Get additional menu items to be added to the main menu\n     *\n     * @return {ItemDefinition[]}\n     */\n    getAdditionalItemDefinitions() {\n        return [];\n    }\n\n    /**\n     * Save plugin setting to persistent storage\n     */\n    saveSetting(key, value) {\n\n    }\n\n}\n", "export default class TurboAdminWpNotices {\n\n    // TODO: Handle empty IDS. Can we identify unique selectors?\n    // See spinup!\n    // Also need to only show move to panel if we can (i.e. if there's a way\n    // to identify it))\n    constructor(rememberedNoticeIds) {\n\n        // Bail if we aren't in the admin\n        if (! document.querySelector('body.wp-admin')) {\n            return;\n        }\n\n        /*\n        * These are the global notice selectors\n        */\n        this.noticeSelectors = [\n            '#wpbody-content > .notice',\n            '#wpbody-content > .wrap > .notice',\n            '#wpbody-content > .wrap > .updated',\n            '#gf_dashboard_message', // Gravity forms\n            '.jitm-banner', //\n            '.fs-notice', // I get this in Replyable\n            '#updraft-dashnotice', // Updraft backups\n            '.woocommerce-message', // WooCommerce\n            '#akismet_setup_prompt', // Akismet\n            '#wf-onboarding-plugin-header', // WordFence onboard\n            '.llar-notice-review' // Limit Login Attempts reloaded\n        ];\n\n        /*\n         * These selectors are allowed (unless explicitly denied)\n         */\n        this.allowedClasses = [\n            'notice-success',\n            'notice-error',\n            'notice-failure',\n            'updated',\n        ]\n\n        if (rememberedNoticeIds) {\n            this.rememberedNoticeIds = rememberedNoticeIds.length > 0 ? rememberedNoticeIds : [];\n        } else {\n            this.rememberedNoticeIds = [];\n        }\n\n        const toolbar = document.getElementById('wpadminbar');\n\n        if (!toolbar) {\n            return;\n        }\n\n        if (rememberedNoticeIds && rememberedNoticeIds.length > 0) {\n            rememberedNoticeIds.forEach(id => {\n                if ('string' === typeof(id) && id.length > 0) {\n                    this.noticeSelectors.push('#' + id);\n                }\n            });\n        }\n\nconsole.log('Notice Selectors', this.noticeSelectors);\n        const notices = document.querySelectorAll(this.noticeSelectors.join(','));\nconsole.log('Notices', notices);\n\n        // Add buttons to notices that can be moved\n        notices.forEach(notice => {\n            this.maybeAddIdToNotice(notice)\n\n            if (this.keepNotice(notice)) {\n                const rememberButton = document.createElement('button');\n                rememberButton.classList.add('ta-remember-notice-button');\n                rememberButton.innerText = 'Move to panel';\n\n                const forgetButton = document.createElement('button');\n                forgetButton.classList.add('ta-forget-notice-button');\n                forgetButton.innerText = 'Move to dashboard';\n\n                notice.classList.add('ta-added-pos-relative');\n\n                notice.appendChild(rememberButton);\n                notice.appendChild(forgetButton);\n\n                rememberButton.addEventListener('click', this.rememberNotice.bind(this), false, true);\n                forgetButton.addEventListener('click', this.forgetNotice.bind(this), false, true);\n            }\n        });\n\n        const noticesToHide = Array.from(notices).filter(notice => {\n            if (this.rememberedNoticeIds.includes(notice.id)) {\n                return true;\n            }\n\n            if (this.keepNotice(notice)) {\n                return false;\n            }\n\n            // Invisible\n            if (\n                notice.offsetHeight === 0 ||\n                notice.offsetWidth === 0\n            ) {\n                return false;\n            }\n\n            return true;\n        })\n\n        console.log('Notices to hide', noticesToHide)\n\n        /**\n         * Build the notices wrapper\n         */\n        /** @type {HTMLDivElement} */\n        const noticesLinkWrapper = document.createElement('div');\n        noticesLinkWrapper.id = 'ta-notices-link-wrap';\n        noticesLinkWrapper.classList.add('hide-if-no-js', 'screen-meta-toggle');\n        noticesLinkWrapper.style.margin='0 0 0 6px';\n        noticesLinkWrapper.style.float='left';\n        if (noticesToHide.length === 0) {\n            noticesLinkWrapper.style.display='none';\n        }\n\n        /**\n         * Add button\n         */\n        /** @type {HTMLButtonElement} */\n        const noticesButton = document.createElement('button');\n        noticesButton.type='button';\n        noticesButton.id='ta-notices-link';\n        noticesButton.classList.add('button', 'show-settings');\n        noticesButton.innerHTML='Notices <span id=\"ta-notice-count\">' + noticesToHide.length + '</span>';\n        noticesButton.setAttribute('aria-controls', 'ta-notices-wrap');\n\n        // This should replicate the functionality from wp-admin/js/common.js\n        // as closely as possible. But note that we can't access the common.js\n        // functions.\n        noticesButton.addEventListener('click', this.toggleNoticesPanel.bind(this), false);\n\n        /**\n         * Add button to the link wrapper\n         */\n        noticesLinkWrapper.appendChild(noticesButton);\n\n        /**\n         * Add the link wrapper to the screen-meta-links section\n         */\n        const screenMetaLinks = document.getElementById('screen-meta-links');\n        screenMetaLinks.appendChild(noticesLinkWrapper);\n\n        /**\n         * Build the panel\n         */\n        const noticesPanel = document.createElement('div');\n\n        noticesPanel.id='ta-notices-wrap';\n        noticesPanel.style.display='none';\n        noticesPanel.dataset.open='no';\n\n        const noticesPanelInner = document.createElement('div');\n        noticesPanelInner.id = 'ta-notices-panel-inner';\n\n        noticesToHide.forEach(notice => {\n            // See Toolbelt's implementation: https://github.com/BinaryMoon/wp-toolbelt/blob/dev/modules/tidy-notifications/src/js/script.js\n            noticesPanelInner.append(notice);\n        });\n\n        /**\n         * Add wrap to the meta area\n         */\n        noticesPanel.appendChild(noticesPanelInner);\n        const screenMeta = document.getElementById('screen-meta');\n        screenMeta.appendChild(noticesPanel);\n\n        // Set up events on the new screen-meta item\n        // if (window.screenMeta) {\n        //     window.screenMeta.init();\n        // }\n    }\n\n    // Does the allowedClasses list say that this notice should be shown?\n    keepNotice(noticeElem) {\n        return this.allowedClasses.reduce( (found, current) => {\n            return found || noticeElem.classList.contains(current)\n        }, false);\n    }\n\n    rememberNotice(ev) {\n        const noticesLinkWrap = document.getElementById('ta-notices-link-wrap');\n        const panel = document.getElementById('wp-admin-bar-ta-notices');\n        const panelInner = document.getElementById('ta-notices-panel-inner');\n        const countElem = document.getElementById('ta-notice-count');\n        const count = parseInt(countElem.innerText, 10);\n        const notice = ev.target.closest(this.noticeSelectors.join(','));\n        const noticeId = notice.id;\n        console.log(`Remembering ${noticeId}`);\n        panelInner.appendChild(notice);\n        if (count === 0) {\n            noticesLinkWrap.style.display = 'block';\n        }\n\n        this.updateScreenMetaHeight();\n\n        countElem.innerText = parseInt(countElem.innerText, 10) + 1;\n\n        this.saveRememberedNotice(noticeId);\n    }\n\n    saveRememberedNotice(noticeId) {\n        this.rememberedNoticeIds.push(noticeId);\n\n        if ('object' === typeof(browser)) {\n            browser.runtime.sendMessage({\n                'action': 'rememberNotice',\n                'noticeId': noticeId,\n            });\n        } else {\n            window.localStorage.setItem('rememberedNoticeIds', JSON.stringify(this.rememberedNoticeIds));\n        }\n    }\n\n    forgetNotice(ev) {\n        const noticesLinkWrap = document.getElementById('ta-notices-link-wrap');\n        const panelInner = document.getElementById('ta-notices-panel-inner');\n        const countElem = document.getElementById('ta-notice-count');\n        const count = parseInt(countElem.innerText, 10);\n        const notice = ev.target.closest(this.noticeSelectors.join(','));\n        const noticeId = notice.id;\n        console.log(`Forgetting ${noticeId}`);\n\n        notice.remove();\n\n        const message = document.createElement('div');\n        const p = document.createElement('p');\n        message.classList.add('notice', 'ta-forget-notice-message');\n        p.textContent = 'Notice will be back in dashboard on next page load';\n        message.appendChild(p);\n        panelInner.appendChild(message);\n\n        this.updateScreenMetaHeight();\n\n        // I was going to to this, but we need to keep the notice about\n        // where the notice has gone.\n        // if (count === 1) {\n        //     noticesLinkWrap.style.display = 'none';\n        // }\n\n        countElem.innerText = (count - 1).toString();\n        this.saveForgottenNotice(noticeId);\n    }\n\n    saveForgottenNotice(noticeId) {\n        this.rememberedNoticeIds.push(noticeId);\n\n        if ('object' === typeof(browser)) {\n            browser.runtime.sendMessage({\n                'action': 'rememberNotice',\n                'noticeId': noticeId,\n            });\n        } else {\n            this.rememberedNoticeIds = this.rememberedNoticeIds.filter( id => id !== noticeId );\n            window.localStorage.setItem('rememberedNoticeIds', JSON.stringify(this.rememberedNoticeIds));\n        }\n    }\n\n    /*\n     * For notices without IDs we'll see if we can add an ID that's a hash of their classlist\n     */\n    maybeAddIdToNotice(notice) {\n        if (notice.id && notice.id !== '' && notice.id !=='message') {\n            return;\n        }\n\n        const classes = notice.classList;\n        notice.id = Array.from(notice.classList).join('-');\n    }\n\n    /**\n     * Detect if WordPress has already applied event handlers to our new screen meta button.\n     *\n     * If it has then WordPress/backbone.js will handle the animation and we won't have to.\n     *\n     * @returns {boolean}\n     */\n    wordpressScreenMetaEventsExist() {\n        return 'object' === typeof(window.screenMeta) && window.screenMeta.toggles.filter('#ta-notices-link').length > 0;\n    }\n\n    updateScreenMetaHeight() {\n        // Don't do this if we're relying on backbone's animation\n        if (this.wordpressScreenMetaEventsExist()) {\n            return;\n        }\n\n        const screenMeta = document.getElementById('screen-meta');\n        const noticesPanel = document.getElementById('ta-notices-wrap');\n        const height = noticesPanel.offsetHeight;\n        screenMeta.style.maxHeight = height.toString(10) + 'px';\n    }\n\n    toggleNoticesPanel(ev) {\n        // We may be in the plugin in which case we don't want to run our handler if there's\n        // a backbone handler on the button.\n        if (this.wordpressScreenMetaEventsExist()) {\n            return;\n        }\n        // Otherwise we mimic the swipe down animation.\n        const animationSeconds = 0.3;\n        const screenMeta = document.getElementById('screen-meta');\n        const noticesPanel = document.getElementById('ta-notices-wrap');\n        if (noticesPanel.dataset.open === 'no') {\n            this.toggleOtherScreenMetaTabs();\n            // Don't ask... just DON'T ask!\n            noticesPanel.dataset.open = 'yes';\n            screenMeta.style.transition = `max-height ${animationSeconds.toString(10)}s`;\n            screenMeta.style.maxHeight = '0';\n            screenMeta.style.overflow = 'hidden';\n            screenMeta.style.display = 'block';\n            noticesPanel.style.display = 'block';\n            const height = noticesPanel.offsetHeight;\n            screenMeta.style.maxHeight = height.toString(10) + 'px';\n            // setTimeout(() => {\n            //     // Nothing to do here.\n            // }, animationSeconds * 1000);\n        } else {\n            noticesPanel.dataset.open = 'no';\n            const height = noticesPanel.offsetHeight;\n            screenMeta.style.maxHeight = '0';\n            setTimeout(() => {\n                noticesPanel.style.display = '';\n                screenMeta.style.display = '';\n                screenMeta.style.transition = '';\n                screenMeta.style.overflow = '';\n                screenMeta.style.maxHeight = '';\n                this.toggleOtherScreenMetaTabs();\n            }, animationSeconds * 1000);\n        }\n\n    }\n\n    toggleOtherScreenMetaTabs() {\n        const otherTabs = document.querySelectorAll('#screen-meta-links .screen-meta-toggle:not(#ta-notices-link-wrap)');\n        otherTabs.forEach( (tab) => {\n            if (tab.style.visibility === 'hidden') {\n                tab.style.visibility = '';\n            } else {\n                tab.style.visibility = 'hidden';\n            }\n        } );\n    }\n}\n", "export default class ListTableShortcuts {\n\n    constructor() {\n        /**\n         * @type {ListTableShortcuts}\n         */\n        const me = this;\n\n        /**\n         * @type {null|HTMLElement}\n         */\n        this.currentRow = null;\n\n        /**\n         * @type {number}\n         */\n        this.currentRowIndex = 0;\n\n        /**\n         * @type {HTMLTableElement}\n         */\n        this.listTable = document.querySelector('.wp-list-table');\n\n        if (! this.listTable) {\n            return;\n        }\n\n        /**\n         * @type {NodeListOf<HTMLTableRowElement>}\n         */\n        this.tableRows = this.listTable.querySelectorAll('tbody#the-list > tr');\n\n        document.addEventListener('keyup', e => this.handleKeyup(e));\n    }\n\n    /**\n     *\n     * @param {KeyboardEvent} ev\n     */\n    handleKeyup(ev) {\n        if (document.activeElement.tagName !== 'BODY') {\n            return;\n        }\n\n        if (ev.key === 'j') {\n            this.tableMoveDown();\n        } else if (ev.key === 'k') {\n            this.tableMoveUp();\n        } else if (ev.key.toLowerCase() === 'enter' && this.currentRow !== null) {\n            this.openTableRowItem();\n        }\n\n    }\n\n    tableMoveDown() {\n        this.preTableChange();\n\n        // Move down\n        if (this.currentRow === null) {\n            this.currentRowIndex = 0;\n        } else {\n            this.currentRowIndex++;\n        }\n        this.updateTable();\n    }\n\n    tableMoveUp() {\n        this.preTableChange();\n\n        if (this.currentRowIndex > 0) {\n            this.currentRowIndex--;\n            this.updateTable();\n        }\n    }\n\n    preTableChange() {\n        if (this.currentRow !== null) {\n            this.tableRows[this.currentRowIndex].classList.remove('ta-active-table-row');\n        }\n    }\n\n    updateTable() {\n        this.currentRow = this.tableRows[this.currentRowIndex];\n\n        if (! this.tableRows[this.currentRowIndex].classList.contains('ta-active-table-row')) {\n            this.tableRows[this.currentRowIndex].classList.add('ta-active-table-row');\n        }\n    }\n\n    openTableRowItem() {\n        console.log(this);\n        /** @type {HTMLAnchorElement} */\n        const link = this.currentRow.querySelector('a.row-title');\n        if (link) {\n            link.click();\n        }\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\n\nexport default class TurboAdminBarkeeper extends TurboAdminPlugin {\n    constructor() {\n        super('Barkeeper');\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        if (true !== globalThis.turboAdmin.options['barkeeper']) {\n            return false;\n        }\n        // Bail if we aren't in the admin\n        if (! document.getElementById('wpadminbar')) {\n            return false;\n        }\n        return true;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n\n        this.exclusionIds = [\n            'wp-admin-bar-menu-toggle',\n            'wp-admin-bar-wp-logo',\n            'wp-admin-bar-site-name',\n            'wp-admin-bar-updates',\n        ];\n\n        this.barkeeperState = globalThis.turboAdmin.options['barkeeper-state'];\n\n        this.root = document.getElementById('wp-admin-bar-root-default');\n        this.itemsToHide = document.querySelectorAll( '#wp-admin-bar-root-default > li');\n\n        Array.from(this.itemsToHide).forEach( element => {\n            if (this.exclusionIds.includes(element.id)) {\n                return;\n            }\n            element.classList.add('ta-barkeeper-collapsable');\n        });\n\n        if (this.barkeeperState === 'closed') {\n            this.root.classList.toggle('ta-barkeeper-closed');\n        }\n\n        // Add toggle\n        this.button = document.createElement('button');\n        this.button.id = 'ta-barkeeper-toggle';\n        this.button.innerText = '<';\n\n        this.button.addEventListener('click', e => {\n            this.root.classList.toggle('ta-barkeeper-closed');\n\n            this.barkeeperState = this.barkeeperState === 'open' ? 'closed' : 'open';\n\n            browser.runtime.sendMessage({\n                'action': 'barkeeperSetState',\n                'barkeeperState': this.barkeeperState,\n            });\n        });\n\n        this.root.insertAdjacentElement('afterend', this.button);\n    }\n\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminContentSearch extends TurboAdminPlugin {\n    constructor() {\n        super('WP Content');\n\n        // Register a search mode for each post type\n        const postTypeKeys = Object.keys(globalThis.contentApi.postTypes);\n        for (let i = 0; i < postTypeKeys.length; i++) {\n            const thisPostTypeKey = postTypeKeys[i];\n            const thisPostType = globalThis.contentApi.postTypes[thisPostTypeKey];\n            // console.log('Adding search mode for post type', thisPostType);\n            this.searchModes.push( this.makePostTypeSearchMode(thisPostType) );\n        }\n\n        // Register ID search mode\n        this.searchModes.push( new SearchMode('id', 'Post ID', this.postById.bind(this)) );\n\n        // Register search all post types mode\n        this.searchModes.push( new SearchMode('search', 'All post types', this.contentSearch.bind(this)) );\n        this.searchModes.push( new SearchMode('find', 'All post types', this.contentSearch.bind(this)) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // TODO: Is this right? Should we check for API access?\n        return true;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * This is a generator for a post-type specific SearchMode object\n     *\n     * @param {Object} postType\n     */\n    makePostTypeSearchMode(postType) {\n        // TODO: interpret the post type name\n        return new SearchMode(postType.slug, postType.name, (searchString) => this.contentSearch(searchString, postType.slug));\n    }\n\n    /**\n     * @param {string} searchString\n     * @param {string} postType This is passed to the API as a subtype. 'any' by default.\n     * @returns {Promise<ContentItem[]>}\n     */\n    async contentSearch(searchString, postType = 'any') {\n        /**\n         * Possible actual code\n         */\n        const results = await globalThis.contentApi.getPosts(searchString, postType);\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            const item = new ContentItem;\n                            item.title = result.title;\n                            item.subtype = result.subtype;\n                            item.url = result.url;\n\n                            item.submenuItems = item.submenuItems.concat(this.makeSubmenuItems(result.id, item))\n\n                            return item;\n                        });\n    }\n\n    /**\n     * @param {string} postId\n     * @returns {Promise<ContentItem[]>}\n     */\n    async postById(postId) {\n        if (! postId.trim().match(/^\\d+$/)) {\n            return [];\n        }\n        const postExists = await globalThis.contentApi.doesPostExist(postId);\n\n        const resultAsContentItem = new ContentItem;\n\n        if (! postExists) {\n            resultAsContentItem.title = 'Post does not exist or is not visible';\n            return [ resultAsContentItem ];\n        }\n\n        resultAsContentItem.title = `Post ID: ${postId}`;\n        resultAsContentItem.url = globalThis.taWp.home + `/?p=${postId}`;\n\n        resultAsContentItem.submenuItems = resultAsContentItem.submenuItems.concat(this.makeSubmenuItems(postId, resultAsContentItem));\n\n        return [ resultAsContentItem ];\n    }\n\n    /**\n     * Makes an array of submenu items from a content item\n     *\n     * @param {number} postId\n     * @param {ContentItem} contentItem\n     * @returns {SubmenuItem[]}\n      */\n    makeSubmenuItems(postId, contentItem) {\n        const itemsToReturn = [];\n        itemsToReturn.push(\n            new SubmenuItem(\n                'View',\n                contentItem.url\n            )\n        );\n\n        // TODO: Make a better way to detect if we are logged in.\n        if (globalThis.turboAdmin.turboAdminPalette.profileLink) {\n            // Need to get edit URL. This seems like the best way for now.\n            const editLink = globalThis.taWp.siteUrl + `/post.php?post=${postId}&action=edit`;\n            itemsToReturn.push(\n                new SubmenuItem(\n                    'Edit',\n                    editLink\n                )\n            )\n\n            // Add oxygen link if needed.\n            if (globalThis.turboAdmin.hasActivatedPlugin('OxygenBuilder')) {\n                const oxygenLink = globalThis.taWp.home + `?page_id=${postId}&ct_builder=true&ct_inner=true`;\n                itemsToReturn.push(\n                    new SubmenuItem(\n                        'Edit with Oxygen',\n                        oxygenLink\n                    )\n                );\n            }\n        }\n\n        const copyLinkItem = new SubmenuItem( 'Copy link', contentItem.url);\n        copyLinkItem.addAttribute('data-action', 'clipboard')\n        itemsToReturn.push(copyLinkItem);\n\n        return itemsToReturn;\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminPluginSearch extends TurboAdminPlugin {\n    constructor() {\n        super('WP Plugins');\n\n        this.searchModes.push( new SearchMode('plugin', 'Plugins', this.pluginSearch, this.defaultPluginItems.bind(this)) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // TODO: Is this right? Should we check for API access?\n        return true;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * Callback to get default items when entering a search mode\n     *\n     * @returns {Promise<ContentItem[]>}\n     */\n    async defaultPluginItems() {\n        return await this.pluginSearch('');\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async pluginSearch(searchString) {\n        /**\n         * Possible actual code\n         */\n        const results = await globalThis.contentApi.getPlugins(searchString);\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            // siteUrl is at globalThis.turboAdmin.wp.siteUrl\n                            const item = new ContentItem;\n                            item.title = result.name;\n                            item.subtype = 'Plugin';\n                            // TODO: Maybe set this to be a search on the plugin screen?\n                            // Plugin \"slug\" is in result.name\n\n                            const itemViewUrlParams = new URLSearchParams();\n                            itemViewUrlParams.set('plugin_status', 'all');\n                            itemViewUrlParams.set('s', result.name);\n                            item.submenuItems.push(\n                                new SubmenuItem(\n                                    'View',\n                                    globalThis.taWp.siteUrl + '/plugins.php?' + itemViewUrlParams.toString()\n                                )\n                            );\n                            // Activate: /wp-admin/plugins.php?action=activate&plugin=order-simulator-woocommerce%2Fwoocommerce-order-simulator.php&plugin_status=all&paged=1&s&_wpnonce=3714a01759\n\n                            return item;\n                        });\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\n\nexport default class TurboAdminUserSearch extends TurboAdminPlugin {\n    constructor() {\n        super('WP Users');\n\n        this.searchModes.push( new SearchMode('user', 'Users', this.userSearch, this.defaultUserItems.bind(this)) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // TODO: Is this right? Should we check for API access?\n        return true;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * Callback to get default items when entering a search mode\n     *\n     * @returns {Promise<ContentItem[]>}\n     */\n     async defaultUserItems() {\n        return await this.userSearch('');\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async userSearch(searchString) {\n        /**\n         * Possible actual code\n         */\n        const results = await globalThis.contentApi.getUsers(searchString);\n\n        if (! Array.isArray(results)) {\n            return [];\n        }\n\n        return results.map(result => {\n                            const item = new ContentItem;\n                            if (result.first_name && result.last_name) {\n                                item.title = `${result.first_name} ${result.last_name} - `;\n                            }\n                            item.title += result.email;\n                            item.subtype = result.roles[0];\n                            item.url = globalThis.taWp.siteUrl + `/user-edit.php?user_id=${result.id}`;\n                            return item;\n                        });\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\n\nexport default class TurboAdminMUSites extends TurboAdminPlugin {\n    constructor() {\n        super('WP Multisite Sites');\n\n        this.searchModes.push( new SearchMode('site', 'Sites', this.siteSearch.bind(this), this.defaultSiteItems.bind(this)) );\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        return Boolean(document.querySelector('#wp-admin-bar-my-sites'));\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * Callback to get default items when entering a search mode\n     *\n     * @returns {Promise<ContentItem[]>}\n     */\n     async defaultSiteItems() {\n        return await this.siteSearch('');\n    }\n\n    /**\n     * @param {string} searchString\n     * @returns {Promise<ContentItem[]>}\n     */\n    async siteSearch(searchString) {\n        // {\n        //     'detectType': 'dom',\n        //     'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-my-sites-list .ab-submenu a',\n        //     'itemTitleFunction': (element) => \"Sites: \" + element.closest('.menupop').querySelector('a').innerText + ' - ' + element.innerText,\n        //     'itemUrlFunction': (element) => element.href\n        // },\n\n        const sites = document.querySelectorAll('#wp-admin-bar-my-sites #wp-admin-bar-my-sites-list > li');\n\n        if (sites.length === 0) {\n            return [];\n        }\n\n        const sitesArray = Array.from(sites);\n        const sitesLinks = sitesArray.map(site => site.querySelector('a'));\n        const filteredSites = sitesLinks.filter(site => site.innerText.toLowerCase().includes(searchString.toLowerCase()));\n\n        return filteredSites.map(site => {\n            const item = new ContentItem;\n            item.title = site.innerText;\n            item.subtype = 'Site';\n            item.url = site.href;\n\n            item.submenuItems = item.submenuItems.concat(this.makeSubmenuItems(site));\n\n            return item;\n        });\n    }\n\n    makeSubmenuItems(siteElement) {\n        const submenuItems = [];\n\n        const submenu = siteElement.nextElementSibling.querySelector(`.ab-submenu`);\n        if (! submenu) {\n            return [];\n        }\n\n        const submenuLinks = submenu.querySelectorAll('a');\n        if (submenuLinks.length === 0) {\n            return [];\n        }\n\n        const submenuLinksArray = Array.from(submenuLinks);\n        submenuLinksArray.forEach(link => {\n            const submenuItem = new SubmenuItem(link.innerText, link.href);\n            submenuItems.push(submenuItem);\n        });\n\n        return submenuItems;\n    }\n}\n", "import TurboAdminPlugin from '../types/class-turbo-admin-plugin.js';\nimport SearchMode from '../types/class-search-mode.js';\nimport ContentItem from '../types/class-content-item.js';\nimport SubmenuItem from '../types/class-submenu-item.js';\nimport ItemDefinition from '../types/class-item-definition.js';\n\nexport default class TurboAdminOxygenBuilder extends TurboAdminPlugin {\n    constructor() {\n        super('OxygenBuilder');\n    }\n\n    /**\n     * Should the plugin activate\n     *\n     * @returns {boolean}\n     */\n    shouldActivate() {\n        // Check for presence of Oxygen Page builder\n        /** @type {HTMLElement|string|Number} */\n        let oxygenLinkElem = document.getElementById('toplevel_page_ct_dashboard_page');\n        // Also check for a menu bar item\n        if (! oxygenLinkElem) {\n            oxygenLinkElem = document.getElementById('wp-admin-bar-oxygen_admin_bar_menu');\n        }\n        // Check to see if Oxygen link is cached\n        if (! oxygenLinkElem) {\n            oxygenLinkElem = Number(window.localStorage.getItem('ta-has-oxygen-builder'));\n        }\n\n        const hasOxygenBuilder = Boolean(oxygenLinkElem);\n\n        // Save Oxygen builder status\n        window.localStorage.setItem('ta-has-oxygen-builder', hasOxygenBuilder ? '1' : '0' );\n\n        return hasOxygenBuilder;\n    }\n\n    /**\n     * Activate and initialise the plugin\n     */\n    activate() {\n        super.activate();\n    }\n\n    /**\n     * Get additional menu items to be added to the main menu\n     *\n     * @return {ItemDefinition[]}\n     */\n     getAdditionalItemDefinitions() {\n        const editDefinition = new ItemDefinition();\n        editDefinition.detectType = 'dom';\n        editDefinition.detectSelector = '#ct-edit-template-builder';\n        editDefinition.itemTitleFunction = () => 'Edit with Oxygen';\n        editDefinition.itemUrlFunction = (element) => element.href;\n        editDefinition.noCache = true;\n\n        // It's worth noting that the Oxygen Builder doesn't use a /wp-admin URL\n        // and so kinda appears to Turbo Admin to be a \"front-end\" page and it\n        // doesn't refresh the menu items.\n        const backToWpDefinition = new ItemDefinition();\n        backToWpDefinition.detectType = 'dom';\n        backToWpDefinition.detectSelector = '.oxygen-back-to-wp-menu .oxygen-toolbar-button-dropdown a:not(:last-of-type)';\n        backToWpDefinition.itemTitleFunction = (element) => 'Back to WP: ' + element.textContent;\n        backToWpDefinition.itemUrlFunction = (element) => {\n            if (element.href) {\n                return element.href;\n            } else {\n                let url = new URL(window.location.href);\n                return url.origin + url.pathname;\n            }\n        };\n        backToWpDefinition.noCache = true;\n\n        return [\n            editDefinition,\n            backToWpDefinition,\n        ];\n    }\n\n}\n", "/*\n * This is the common Turbo Admin library.\n *\n * It's (currently) WordPress-specific, but can be loaded by\n * either the Extension OR the Plugin\n *\n * It takes an options object:\n *\n * options: {\n *   shortcutKeys: [\n *     // Array of shortcut key definitions, like:\n *     {\n *       {\n *         meta: false,\n *         alt: true,\n *         ctrl: true,\n *         shift: true,\n *         key: 'p'\n *       }\n *     }\n *   ],\n *   appendToElement {\n *     // Optional CSS selector to define what to append the palette to\n *     'body'\n *   },\n *   extraItems: [\n *     // Optional array of extra item configs used to generate new item objects\n *     {\n *       'detectType': 'url',\n *       'detectPattern': 'wp-login',\n *       'itemTitle': 'View/visit site',\n *       'itemUrlFunction': () => this.home\n *     },\n *   ],\n *   extraItemsRaw: [\n *     // Optional array of raw item objects to be added\n *     {\n *       'title': ,\n *       'action': ,\n *       'parentTitle': ,\n *     }\n *   ]\n * }\n */\n\nimport TurboAdminPalette from './class-turbo-admin-palette.js';\nimport TurboAdminMenuItem from './types/class-turbo-admin-menu-item.js';\nimport SearchMode from './types/class-search-mode.js';\nimport TurboAdminPlugin from './types/class-turbo-admin-plugin.js';\nimport Acf from './plugins/class-acf.js';\n// import TurboAdminWpBlockEditorFullscreenKill from './class-turbo-admin-wp-block-editor-fullscreen-kill.js';\n// import TurboAdminWpBlockEditorWelcomeGuideKill from './class-turbo-admin-wp-block-editor-welcome-guide-kill.js';\nimport TurboAdminWpNotices from './class-turbo-admin-wp-notices.js';\nimport TurboAdminListTableShortcuts from './class-list-table-shortcuts.js';\nimport TurboAdminBarkeeper from './plugins/class-turbo-admin-barkeeper.js';\nimport TurboAdminContentSearch from './plugins/class-turbo-admin-content-search.js';\nimport TurboAdminPluginSearch from './plugins/class-turbo-admin-plugins.js';\nimport TurboAdminUserSearch from './plugins/class-turbo-admin-users.js';\n// import TurboAdminWoocommerce from './plugins/class-turbo-admin-woocommerce.js';\n// import TurboAdminGravityForms from './plugins/class-turbo-admin-gravity-forms.js';\nimport TurboAdminMUSites from './plugins/class-turbo-admin-mu-sites.js';\nimport TurboAdminOxygenBuilder from './plugins/class-turbo-admin-oxygen-buillder.js';\n\nexport default class TurboAdmin {\n\n    /**\n     * @param {*} options\n     * @returns {TurboAdmin}\n     */\n    constructor(options) {\n        // Sometimes we get a second copy of TA running, like if the plugin is running too.\n        // Is this case we want to skip the initialisation.\n        this.doInit = true;\n\n        if (document.getElementById('ta-command-palette-container')) {\n            console.log('TurboAdmin already initialised - I won\\'t make a second copy!');\n            this.doInit = false;\n            return globalThis.turboAdmin;\n        }\n\n        this.options = options;\n        this.plugins = {};\n\n        // TODO: Something? What should this type be?\n        this.searchModes = {};\n\n        // On the front end we set this if there is no saved menu.\n        this.menuNeedsRefresh = false;\n    }\n\n    /**\n     * Perform initialization - this is all the things that do not need APIs to\n     * get set up.\n     */\n    async init() {\n        if (! this.doInit) {\n            return;\n        }\n\n        // Register all the plugins\n        new TurboAdminBarkeeper();\n        new TurboAdminContentSearch();\n        new TurboAdminPluginSearch();\n        new TurboAdminUserSearch();\n        // new TurboAdminWoocommerce();\n        // new TurboAdminGravityForms();\n        new TurboAdminMUSites();\n        new TurboAdminOxygenBuilder();\n\n        // Grab the global Wp object instance\n        this.wp = globalThis.taWp;\n\n        this.menu = [];\n\n        // Check for saved menu when on front-end\n        if (! this.wp.isBackend) {\n            // Only use the cached items if the current URL matches the last site URL\n            // This handles changes of multi-site site!\n            // We ONLY need to do this on the front-end as the back-end will always\n            // refresh the menu.\n            if (! this.wp.siteChanged) {\n                // Check for .logged-in class on body - if logged in, we can use the saved menu,\n                // if it exists.\n                if (document.body.classList.contains('logged-in')) {\n                    // Get from localStorage\n                    const savedMenu = window.localStorage.getItem('ta-palette-data');\n\n                    // This attempts to see if we have cached items from the back-en\n                    if (null === savedMenu) {\n                        this.menuNeedsRefresh = true;\n                    } else {\n                        this.menu = JSON.parse(savedMenu);\n                        // Check if there is no \"Media\" item  - this should ONLY be in the back-end\n                        if (! this.menu.some(item => item.action.endsWith('upload.php'))) {\n                            this.menuNeedsRefresh = true;\n                        }\n                        // Merge (?) the items?\n                    }\n                }\n            }\n        } else {\n            // On the back end, get the WordPress dashboard menu items\n            this.menu = this.getMenu();\n        }\n\n        // Add other additional items\n        this.addAdditionalMenuItems();\n        // Add items passed in using extraItemsRaw\n        this.menu = this.menu.concat(this.options.extraItemsRaw ?? []);\n\n        // Add ACF items?\n        // TODO: Make this better. Possible ASYNC somehow?\n        // this.acf = new Acf();\n        // if (this.acf.isAcfInstalled()) {\n        //     const acfLinks = await this.acf.getFieldGroups()\n        //     // console.table(acfItems);\n        //     const acfMenuItems = acfLinks.map(\n        //         item => new TurboAdminMenuItem(\n        //             item.label + ' (ACF)',\n        //             item.link,\n        //             ''\n        //         )\n        //     );\n        //     this.menu = this.menu.concat(acfMenuItems);\n        // }\n\n        // Sort the menu\n        this.menu.sort((a, b) => (a.parentTitle + a.title).localeCompare(b.parentTitle + b.title));\n\n        // Filter out no-cache items and save to localStorage.\n        const itemsToSave = this.menu.filter(item => (! item.noCache));\n        window.localStorage.setItem('ta-palette-data', JSON.stringify(itemsToSave));\n\n        // Add palette markup to the DOM\n        this.addPalette();\n        // Initialise controls on the palette\n        this.turboAdminPalette = new TurboAdminPalette(this.menu, this.options);\n    }\n\n    /**\n     * These are initialization steps that DO needs APIs to be set up.\n     */\n    activatePlugins() {\n        // Initialize all plugins\n        Object.keys(this.plugins).forEach( plugin => {\n            if (this.plugins[plugin].shouldActivate()) {\n                this.plugins[plugin].activate();\n            }\n        })\n\n        // if (true === this.options['block-editor-fullscreen-disable']) {\n        //     // Initialise fullscreen kill\n        //     this.turboAdminFullscreenKill = new TurboAdminWpBlockEditorFullscreenKill();\n        // }\n\n        // if (true === this.options['block-editor-welcome-screen-kill']) {\n        //     this.turboAdminWelcomeKill = new TurboAdminWpBlockEditorWelcomeGuideKill();\n        // }\n\n        if (true === this.options['list-table-keyboard-shortcuts']) {\n            this.turboAdminListTableShortcuts = new TurboAdminListTableShortcuts();\n        }\n\n        // Add other things if we're logged in and have an API nonce\n        if (globalThis.contentApi.userLoggedIn()) {\n            // What shall we do?\n        }\n    }\n\n    /**\n     * True if the plugin has been activated\n     *\n     * @param {string} name Name of the plugin to check for\n     * @returns {boolean}\n     */\n    hasActivatedPlugin(name) {\n        return Object.keys(this.plugins).includes(name) &&\n            this.plugins[name].activated;\n    }\n\n    /**\n     * Gather the WordPress dashboard admin (sidebar) menu items\n     *\n     * @returns { TurboAdminMenuItem[] }\n     */\n    getMenu() {\n        const items = [];\n        const menuTop = document.getElementById('adminmenu');\n        if (menuTop) {\n            const topDOMItems = menuTop.querySelectorAll('li.menu-top');\n            topDOMItems.forEach(el => {\n                const a = el.querySelector('a.menu-top');\n                const title = a.querySelector('.wp-menu-name').innerHTML;\n                const action = a.href;\n                const parentTitle = '';\n                const item = new TurboAdminMenuItem(title, action, parentTitle);\n                items.push(item);\n\n                const subMenu = el.querySelector('.wp-submenu');\n                if (!subMenu) {\n                    return;\n                }\n                const subItems = subMenu.querySelectorAll('li a');\n                if (!subItems) {\n                    return;\n                }\n                subItems.forEach(subEl => {\n                    const parentTitle = title;\n                    const childTitle = subEl.innerHTML;\n                    const childAction = subEl.href;\n                    const item = new TurboAdminMenuItem(childTitle, childAction, parentTitle);\n                    items.push(item);\n                })\n            });\n        }\n        return items;\n    }\n\n    /**\n     * Adds additional menu items passed in by configuration to the\n     * menu items list.\n     */\n    addAdditionalMenuItems() {\n\n        /*\n         * I'd LOVE for this to be config driven\n         *\n         * [\n         *   {\n         *     'detectType': 'url',\n         *     'detectPattern': 'wp-login',\n         *     'itemTitle': 'View/visit site',\n         *     'itemUrlFunction': () => this.home\n         *   },\n         *   {\n         *     'detectType': 'dom',\n         *     'detectSelector': '#wpadminbar',\n         *     'itemTitle': 'Logout',\n         *     'itemUrlFunction': () => logoutUrl\n         *   }\n         *  Can we add actionTypes as well? To do clicks and navigates?\n         * ]\n         */\n\n        // Get passed-in extraItems\n        // Technically this is an array of {ItemDefintion} but more work needed to make that happen.\n        let extraItems = this.options.extraItems ?? [];\n\n        // Get any extra items defined by plugins\n        const pluginKeys = Object.keys(this.plugins);\n\n        for (let i=0; i < pluginKeys.length; i++) {\n            extraItems = extraItems.concat(this.plugins[pluginKeys[i]].getAdditionalItemDefinitions());\n        }\n\n        // Merge in defaults\n        extraItems = extraItems.concat(\n            [\n                {\n                    'detectType': 'dom',\n                    'detectSelector': 'body.wp-admin #wp-admin-bar-view-site a',\n                    'itemTitleFunction': () => 'View/visit site',\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-dashboard a',\n                    'itemTitleFunction': (element) => element.textContent,\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wpadminbar',\n                    'itemTitleFunction': () => 'Logout',\n                    'itemUrlFunction': () => document.getElementById('wp-admin-bar-logout')?.querySelector('a')?.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-edit a',\n                    'itemTitleFunction': (item) => item.textContent,\n                    'itemUrlFunction': (item) => item.href,\n                    'noCache': true,\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-view a',\n                    'itemTitleFunction': (item) => item.textContent,\n                    'itemUrlFunction': (item) => item.href,\n                    'noCache': true,\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-new-content .ab-submenu a',\n                    'itemTitleFunction': (item) => 'New ' + item.textContent,\n                    'itemUrlFunction': (item) => item.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-customize a',\n                    'itemTitleFunction': (item) => item.textContent,\n                    'itemUrlFunction': (item) => item.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelectorNone': '#wpadminbar, #loginform',\n                    'itemTitleFunction': () => \"Log in\",\n                    'itemUrlFunction': () => {\n                        if (globalThis.taWp.home) {\n                            return globalThis.taWp.siteUrl;\n                        }\n                        // Try getting wp-admin\n                        return 'javascript:alert(\\'Sorry, could not detect login URL.\\')';\n                    }\n                },\n                // This is on the login screen\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#backtoblog a',\n                    'itemTitleFunction': () => \"View/visit site\",\n                    'itemUrlFunction': (element) => element.href\n                },\n                // Multisite items\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-network-admin > a',\n                    'itemTitleFunction': () => \"Network Admin\",\n                    'itemUrlFunction': (element) => element.href\n                },\n                {\n                    'detectType': 'dom',\n                    'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-network-admin .ab-submenu a',\n                    'itemTitleFunction': (element) => 'Network Admin: ' + element.textContent,\n                    'itemUrlFunction': (element) => element.href\n                },\n            ]\n        );\n\n        extraItems.forEach(item => {\n            let detected = false;\n            let elements = null;\n            if (item.detectType === 'url') {\n                detected = Boolean(window.location.href.includes(item.detectPattern));\n            } else if (item.detectType === 'dom') {\n                if (item.detectSelector) {\n                    elements = document.querySelectorAll(item.detectSelector);\n                    detected = Boolean(elements);\n                } else if (item.detectSelectorNone) {\n                    elements = document.querySelectorAll(item.detectSelectorNone);\n                    detected = elements.length === 0;\n                    // Need to pass SOMETHING to the loop below\n                    elements = document.querySelectorAll('body');\n                }\n            }\n            if (!detected) {\n                return;\n            }\n\n            elements.forEach(element => {\n                const newItem = new TurboAdminMenuItem(item.itemTitleFunction(element), item.itemUrlFunction(element), '', item?.noCache);\n                // Might already have one so check.\n                if (this.menu.some(menuItem => {\n                    // This must be newItem.sameAs, not menuItem.sameAs because the menuItem\n                    // may have been loaded from saved menu and may not actually be an instance\n                    // of a TurboAdminMenuItem.\n                    return newItem.sameAs(menuItem)\n                } )) {\n                    return;\n                }\n                // We don't already have one. So add it.\n                this.menu.push(newItem);\n            });\n        })\n    }\n\n    /**\n     * Builds the palette HTML and adds it to the DOM.\n     */\n    addPalette() {\n        const container = document.createElement('div');\n        container.id = 'ta-command-palette-container';\n        // Palette\n        const palette = document.createElement('div');\n        palette.id = 'ta-command-palette';\n        // Palette notice\n        const paletteNotice = document.createElement('div');\n        paletteNotice.id = 'ta-command-palette-notice';\n        // Tab notice\n        const tabNotice = document.createElement('div');\n        tabNotice.id = 'ta-command-palette-tab-notice';\n        // Tab notice text\n        const tabNoticeText = document.createElement('span');\n        tabNoticeText.id = 'ta-command-palette-tab-notice-text';\n        // Tab notice \"button\"\n        const tabNoticeButton = document.createElement('span');\n        tabNoticeButton.id = 'ta-command-palette-tab-notice-button';\n        tabNoticeButton.innerText = 'Tab';\n        // Input field\n        const input = document.createElement('input');\n        input.id = \"ta-command-palette-input\";\n        input.name = \"ta-command-palette-input\";\n        input.type = \"text\";\n        // Set this to stop stuff trying to fill it.\n        input.setAttribute('autocomplete', 'off');\n        // Search mode tag\n        const searchModeTag = document.createElement('div');\n        searchModeTag.id = 'ta-command-palette-search-mode-tag';\n        // List container (needed to contain the main list and the submenu list)\n        const listContainer = document.createElement('div');\n        listContainer.id = \"ta-command-palette-items-container\";\n        // List\n        const list = document.createElement('ul');\n        list.id = \"ta-command-palette-items\";\n        // Sub-menu list\n        const submenuContainer = document.createElement('div');\n        submenuContainer.id = \"ta-command-palette-submenu-container\";\n        // Join it all up\n        container.appendChild(palette);\n        palette.appendChild(searchModeTag);\n        palette.appendChild(paletteNotice);\n        tabNotice.appendChild(tabNoticeText);\n        tabNotice.appendChild(tabNoticeButton);\n        palette.appendChild(tabNotice);\n        palette.appendChild(input);\n        listContainer.appendChild(list);\n        listContainer.appendChild(submenuContainer);\n        palette.appendChild(listContainer);\n\n        if (document.getElementById('wpadminbar') && this.options['admin-bar-search'] === true) {\n            const paletteLi = document.createElement('li');\n            paletteLi.appendChild(container);\n            const adminBar = document.getElementById('wp-admin-bar-top-secondary');\n            adminBar.appendChild(paletteLi);\n\n            // Add focus handler\n            input.addEventListener('focus', e => this.turboAdminPalette.showPalette());\n\n            // Add placeholder\n            const placeholder = document.createElement('div');\n            placeholder.id = 'ta-shortcut-key-placeholder';\n            placeholder.innerText = this.buildShortcutKeysString();\n            placeholder.addEventListener('click', e => input.focus());\n\n            palette.insertBefore( placeholder, listContainer );\n        } else {\n            // Container\n            document.querySelector(this.options.appendToElement ?? 'body').appendChild(container);\n        }\n    }\n\n    /**\n     * Register a plugin with Turbo Admin\n     *\n     * @param {TurboAdminPlugin} plugin\n     */\n    registerPlugin(plugin) {\n        console.log('Registering plugin ' + plugin.name);\n        this.plugins[plugin.name] = plugin;\n    }\n\n    /**\n     * Register a palette search mode and its associated plugin\n     *\n     * this is usually bound to the searchMode, so\n     *\n     * @param {SearchMode} searchMode\n     */\n    registerSearchMode(searchMode) {\n        console.log('Registering search mode with keyword ' + searchMode.keyword);\n        // Don't use `this` as we are bound!\n        globalThis.turboAdmin.searchModes[searchMode.keyword] = searchMode;\n    }\n\n    /**\n     * Returns a string representation of the palette's keyboard shortcut\n     *\n     * @returns { String }\n     */\n    buildShortcutKeysString () {\n        let keysString = '';\n        let shortcut = this.options.shortcutKeys[0];\n\n        if ( shortcut.meta ) {\n            keysString += 'Cmd-';\n        }\n        if ( shortcut.ctrl ) {\n            keysString += 'Ctrl-';\n        }\n        if ( shortcut.alt ) {\n            keysString += 'Alt-';\n        }\n        if ( shortcut.shift ) {\n            keysString += 'Shift-';\n        }\n        keysString += shortcut.key;\n        return keysString;\n    }\n\n}\n", "export default class Wp {\n\n    constructor() {\n\n        // Set home and siteUrl\n        this.siteUrl = '';\n        this.home = '';\n        this.loginUrl = '';\n        this.apiLinkUrl = '';\n    }\n\n    async completeInit() {\n        // Fetch previously loaded site URL\n        this.previousUrl = window.localStorage.getItem('ta-palette-data-site');\n\n        // Fetch previously-stored siteUrl and home\n        this.siteUrl = window.localStorage.getItem('ta-palette-data-siteurl');\n        this.home = window.localStorage.getItem('ta-palette-data-home');\n\n        /**\n         * Are we in the back-end?\n         */\n        this.isBackend = this.getIsBackend();\n\n        /**\n         * Figure out all the WP URLs\n         */\n        await this.getUrls();\n\n        /**\n         * Tells you if the best-guess site URL of the current page is different\n         * to that of the previously saved site URL.\n         */\n        this.siteChanged = this.home !== this.previousUrl;\n\n        // Save current site URL for next time\n        window.localStorage.setItem('ta-palette-data-site', this.home);\n    }\n\n    getIsBackend() {\n        return document.body.classList.contains('wp-admin');\n    }\n\n    /**\n     * Return the URL with a trailing slash if it didn't already have one.\n     *\n     * @param {String} url The URL to check\n     * @return {String}    The resulting URL\n     */\n    ensureTrailingSlash( url ) {\n        if (url.endsWith('/')) {\n            return url;\n        } else {\n            return url + '/';\n        }\n    }\n\n    /**\n     * Tests if a URL works and, if redirected, that the final URL contains a given\n     * string. Returns the final, redirected-to URL if the test passed, or false\n     * otherwise.\n     *\n     * @param {String} url                    The URL to test.\n     * @param {String} responseUrlMustContain The string to test against the final URL\n     * @returns {Promise<String|Boolean>}   The final URL or false.\n     */\n    async testUrl(url, responseUrlMustContain='') {\n\n        /** @type {RequestInit} */\n        const init = {\n            method: 'HEAD',\n            mode: 'cors',\n            cache: 'no-cache',\n            credentials: 'same-origin'\n        }\n\n        const response = await fetch(url, init);\n\n        if (response.redirected && !response.url.includes(responseUrlMustContain)) {\n            return false;\n        }\n\n        if ( ! response.ok ) {\n            return false;\n        }\n\n        return response.url;\n    }\n\n    async findWhichUrlWorks(urls, responseUrlMustContain='') {\n        let workingUrl = false;\n        let result;\n        // This has to be a for loop rather than reduce or forEach as separate\n        // async callbacks would be launched asynchronously.\n        for (let i=0; i<urls.length; i++) {\n            if (workingUrl) continue;\n            result = await this.testUrl(urls[i], responseUrlMustContain);\n            if (result !== false) {\n                workingUrl = result;\n            }\n        }\n        return workingUrl;\n    }\n\n    /**\n     *\n     * @param {String} homeUrl\n     */\n    async guessSiteUrlFromHome( homeUrl ) {\n        const homeWithSlash = this.ensureTrailingSlash(homeUrl);\n\n        // NOTE: Backed out of this until I can make it work async.\n        // Might not even be a good idea anyway.\n\n        // const possibleUrls = [\n        //     homeWithSlash + 'wp-admin/',\n        //     homeWithSlash + 'wp/wp-admin'\n        // ];\n        // return this.findWhichUrlWorks(possibleUrls, 'wp-admin');\n        return homeWithSlash + 'wp-admin/';\n    }\n\n    /**\n     *\n     * @param {String} homeUrl\n     */\n    async guessHome() {\n        const currentUrl = new URL(window.location);\n        const origin = this.ensureTrailingSlash(currentUrl.origin);\n\n        // NOTE: Backed out of this until I can make it work async.\n        // Might not even be a good idea anyway.\n\n        // const possibleUrls = [\n        //     origin\n        // ];\n        // return this.findWhichUrlWorks(possibleUrls, 'wp-admin');\n        return origin;\n    }\n\n    /**\n     *\n     * @param {String} siteUrl\n     * @returns {String}\n     */\n    guessHomeFromSiteUrl(siteUrl) {\n        // Not much we can do here.\n        return siteUrl.replace(/wp-admin\\/?/, '');\n    }\n\n    async getUrls() {\n        // See if we can actually find the URL for the API\n        /** @type {HTMLLinkElement|null} */\n        const apiLink = document.querySelector('link[rel=\"https://api.w.org/\"]');\n\n        if (apiLink) {\n            this.apiLinkUrl = apiLink.href;\n        }\n        // Figure out the siteurl and home - this is different on the front and back end\n        if (this.isBackend) {\n            // This is easy in the back end/Dashboard!\n            this.siteUrl = window.location.href.match(/(^.*wp-admin)/)[1];\n            this.home = document.getElementById('wp-admin-bar-site-name').querySelector('a').href;\n\n            // Always set the siteUrl and home as this is definitive\n            window.localStorage.setItem('ta-palette-data-siteurl', this.siteUrl);\n            window.localStorage.setItem('ta-palette-data-home', this.home);\n        } else if (! this.siteUrl || ! this.home) {\n\n            // If we're not in the backend then (in the extension at least) we\n            // could be on the front-end and not logged in, so check for an\n            // admin bar and grab from that if there is one.\n            if (document.getElementById('wpadminbar')) {\n                this.siteUrl = document.getElementById('wp-admin-bar-dashboard').querySelector('a').href;\n                // Try for the API link\n                if (this.apiLinkUrl) {\n                    if (this.apiLinkUrl.includes('/wp-json')) {\n                        this.home = this.apiLinkUrl.replace('wp-json/', '');\n                    }\n                    if (this.apiLinkUrl.includes('index.php?rest_route')) {\n                        this.home = this.apiLinkUrl.replace(/index.php\\?rest_route.*/, '');\n                    }\n                } else {\n                    // We know what the siteUrl is, so guess the home from the siteUrl\n                    this.home = this.guessHomeFromSiteUrl(this.siteUrl);\n                }\n\n            } else {\n                // Try for the API link\n                // TODO: This needs to be async so it doesn't hold things up.\n                if (this.apiLinkUrl) {\n                    if (this.apiLinkUrl.includes('/wp-json')) {\n                        this.home = this.apiLinkUrl.replace('wp-json/', '');\n                    }\n                    if (this.apiLinkUrl.includes('index.php?rest_route')) {\n                        this.home = this.apiLinkUrl.replace(/index.php\\?rest_route.*/, '');\n                    }\n                    // We (probably) know what the home link is now, so guess the wp-admin\n                    if (this.home) {\n                        this.siteUrl = await this.guessSiteUrlFromHome( this.home );\n                    } else {\n                        this.siteUrl = this.guessSiteUrl();\n                    }\n                } else {\n                    // We got nothing.\n                    this.home    = await this.guessHome();\n                    if (this.home) {\n                        this.siteUrl = await this.guessSiteUrlFromHome(this.home);\n                    }\n                }\n            }\n        }\n\n        // Always trim the / for comparisons\n        if (this.siteUrl) {\n            this.siteUrl = this.siteUrl.replace(/(.+)\\/$/, '$1');\n        }\n        if (this.home) {\n            this.home = this.home.replace(/(.+)\\/$/, '$1');\n        }\n\n        // console.log('siteUrl: ', this.siteUrl);\n        // console.log('home: ', this.home);\n    }\n\n}\n", "import Storage from '../class-storage.js';\n// import ContentApi from './class-content-api.js';\n\nexport default class WoocommerceApi {\n\n    constructor() {\n        // This is used to \"cache\" duplicate requests.\n        // It's an object because it will have search strings as keys\n        this.cache = {};\n    }\n\n    async getOrders(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['orders-' + searchString]) {\n            return this.cache['orders-' + searchString];\n        }\n\n        // Fetch results\n        const response = await this.wooGet(\n            \"orders\",\n            {\n                search: searchString,\n                per_page: 100,\n            }\n        );\n\n        if (response === false) {\n            return false;\n        }\n\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['orders-' + searchString] = result;\n\n        return result;\n    }\n\n    async getOrder(orderId) {\n        // Check the cache\n        if (undefined !== this.cache['order-' + orderId]) {\n            return this.cache['order-' + orderId];\n        }\n\n        // Fetch results\n        const response = await this.wooGet(\n            `orders/${orderId}`\n        );\n\n        if (response === false) {\n            return false;\n        }\n\n        // Decode JSON\n        const result = await response.json();\n\n        let resultAsArray = [ result ];\n\n        // Store in the cache\n        this.cache['order-' + orderId] = resultAsArray;\n\n        return resultAsArray;\n    }\n\n    async getCustomers(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['customers-' + searchString]) {\n            return this.cache['customers-' + searchString];\n        }\n\n        // Fetch results\n        const response = await this.wooGet(\n            \"customers\",\n            {\n                search: searchString,\n                per_page: 100,\n                role: 'all',\n            }\n        );\n\n        if (response === false) {\n            return false;\n        }\n        // Decode JSON\n        const result = await response.json();\n\n        // Store in the cache\n        this.cache['customers-' + searchString] = result;\n\n        return result;\n    }\n\n    // TODO: Add docblock and types\n    async wooGet(path, data = {}) {\n        const wooApiBase = globalThis.contentApi.apiRoot + 'wc/v3/';\n\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n            credentials: 'include'\n        }\n\n        // Add the nonce if there is one\n        if (globalThis.contentApi.apiNonce) {\n            data._wpnonce = globalThis.contentApi.apiNonce;\n        }\n\n        const params = globalThis.contentApi.makeParamString(data);\n\n        const response = await fetch(`${wooApiBase}${path}/?${params}`, init);\n\n        if ( response.status === 404 ) {\n            return false;\n        }\n        if ( (response.status < 200 || response.status >= 300) ) {\n            globalThis.turboAdmin.turboAdminPalette.showPaletteNotice('WooCommerce API Error. Try visiting the dashboard to refresh things.');\n        }\n\n        return response;\n    }\n\n}\n", "import Storage from '../class-storage.js';\n// import ContentApi from './class-content-api.js';\n\nexport default class GravityFormsApi {\n\n    constructor() {\n        // This is used to \"cache\" duplicate requests.\n        // It's an object because it will have search strings as keys\n        this.cache = {};\n    }\n\n    async getForms(searchString) {\n        // Check the cache\n        if (undefined !== this.cache['gf-forms-' + searchString]) {\n            return this.cache['gf-forms-' + searchString];\n        }\n\n        // Fetch results\n        const response = await this.gfGet(\n            \"forms\",\n            {}\n        );\n\n        // Decode JSON\n        const result = await response.json();\n\n        // TODO: Trap for errors\n\n        // Filter by search string - the API doesn't do this for us\n        const searchStringLowerCase = searchString.toLowerCase();\n        const formIds = Object.keys(result);\n        for (let k = 0; k < formIds.length; k++) {\n            const thisId = formIds[k];\n            if (! result[thisId].title.toLowerCase().includes(searchStringLowerCase)) {\n                delete result[thisId];\n            }\n        }\n\n        // Store in the cache\n        this.cache['gf-forms-' + searchString] = result;\n\n        return result;\n    }\n\n    async gfGet(path, data = {}) {\n        const gfApiBase = globalThis.contentApi.apiRoot + 'gf/v2/';\n\n        const init = {\n            method: 'GET',\n            headers: {},\n            mode: 'cors',\n            cache: 'no-store',\n            credentials: 'include'\n        }\n\n        // Add the nonce if there is one\n        if (globalThis.contentApi.apiNonce) {\n            data._wpnonce = globalThis.contentApi.apiNonce;\n        }\n\n        const params = globalThis.contentApi.makeParamString(data);\n\n        const response = await fetch(`${gfApiBase}${path}/?${params}`);\n\n        if (response.status < 200 || response.status >= 300) {\n            globalThis.turboAdmin.turboAdminPalette.showPaletteNotice('Gravity Forms API Error. Try visiting the dashboard to refresh things.');\n        }\n\n        return response;\n    }\n\n}\n", "import TurboAdmin from './class-turbo-admin.js';\nimport ContentApi from './apis/class-content-api.js';\nimport Wp from './class-wp.js';\nimport TurboAdminWpNotices from './class-turbo-admin-wp-notices.js';\nimport WoocommerceApi from './apis/class-woocommerce-api.js';\nimport GravityFormsApi from './apis/class-gravity-forms-api.js';\n\nconst taStorageKey = 'turbo-admin-settings';\n\n// Use this to clear storage\n// browser.storage.local.remove(taStorageKey).then();\n\n// Note that in the extension, the globalThis is not the browser's global scope,\n// it is sandboxed. So we can't check across the plugin/extension boundary here.\nasync function taInit(settings) {\n\n    if (typeof(globalThis.turboAdmin) !== 'undefined') {\n        // Already initialised for some reason\n        return;\n    }\n    globalThis.turboAdmin = null;\n\n    // Handle empty settings\n    if (typeof(settings[taStorageKey]) === 'undefined') {\n        console.log('Weird. Turbo Admin could not find any settings');\n        return;\n    }\n\n    globalThis.turboAdminOptions = settings[taStorageKey];\n\n    console.log('Preparing Turbo Admin');\n\n    // Get Wp stuff ready\n    globalThis.taWp = new Wp();\n\n    // Parts of this init are async.\n    await globalThis.taWp.completeInit();\n\n    console.log('Turbo Admin: WP is initialised');\n\n    // Get/set api settings\n    globalThis.contentApi = new ContentApi();\n    await globalThis.contentApi.discoverApiRoot();\n    await globalThis.contentApi.discoverPostTypes();\n    globalThis.woocommerceApi = new WoocommerceApi();\n    globalThis.gravityFormsApi = new GravityFormsApi();\n\n    console.log('Turbo Admin: Content API is initialised');\n\n    globalThis.turboAdmin = new TurboAdmin(globalThis.turboAdminOptions);\n    await globalThis.turboAdmin.init();\n\n\n\n    // This needs all the APIs to be ready\n    await globalThis.turboAdmin.activatePlugins();\n\n    if (settings[taStorageKey]['hide-notices']) {\n        globalThis.turboAdminWpNotices = new TurboAdminWpNotices(settings[taStorageKey].rememberedNoticeIds);\n    }\n}\n\n/**\n * This is plugin-specific. It should not be present in the extension code.\n */\ndocument.addEventListener('DOMContentLoaded', async e => {\n\tglobalThis.turboAdminOptions = {};\n\tglobalThis.turboAdminOptions[taStorageKey] = {\n\t\t// wpTurboAdmin is set using wp_localize_script\n\t\tshortcutKeys: globalThis.wpTurboAdmin.keys,\n        // These don't apply to the plugin version\n        'block-editor-fullscreen-disable': false,\n        'block-editor-welcome-screen-kill': false,\n        // I don't think we'll do this in the plugin as the code would be SO different.\n        'live-dev-notice': false,\n        'list-table-keyboard-shortcuts': globalThis.wpTurboAdmin['listTableShortcuts'] === '1',\n        'hide-notices': globalThis.wpTurboAdmin['hideNotices'] === '1',\n        'rememberedNoticeIds': JSON.parse(window.localStorage.getItem('rememberedNoticeIds')) ?? new Array(),\n        'barkeeper': globalThis.wpTurboAdmin['barkeeper'] === '1',\n        'admin-bar-search': globalThis.wpTurboAdmin['adminBarSearch'] === '1',\n\t}\n\tawait taInit(globalThis.turboAdminOptions);\n});\n"],
     5  "mappings": ";;;;;;;;;;;;;;;;;;;;;;AAAA;AAQA,QAAI;AAAJ,QAAO;AAAG,QAAI,SAAM,IAAI,WAAY;AAAE;AAAc,kBAAW,IAAG;AAAE,eAAQ,MAAI,AAAc,OAAO,UAArB,cAA+B,AAAY,OAAO,OAAO,YAA1B,WAAqC,SAAU,IAAG;AAAE,iBAAO,OAAO;AAAA,YAAM,SAAU,IAAG;AAAE,iBAAO,MAAK,AAAc,OAAO,UAArB,cAA+B,GAAE,gBAAgB,UAAU,OAAM,OAAO,YAAY,WAAW,OAAO;AAAA,WAAK;AAAA;AAAK,kBAAW,IAAG,IAAG;AAAE,YAAI,CAAE,eAAa;AAAI,gBAAM,IAAI,UAAU;AAAA;AAAuC,iBAAW,IAAG,IAAG;AAAE,iBAAS,KAAI,GAAG,KAAI,GAAE,QAAQ,MAAK;AAAE,cAAI,KAAI,GAAE;AAAI,aAAE,aAAa,GAAE,cAAc,OAAI,GAAE,eAAe,MAAI,WAAW,MAAM,IAAE,WAAW,OAAK,OAAO,eAAe,IAAG,GAAE,KAAK;AAAA;AAAA;AAAO,iBAAW,IAAG,IAAG,IAAG;AAAE,eAAO,MAAK,EAAE,GAAE,WAAW,KAAI,MAAK,EAAE,IAAG,KAAI;AAAA;AAAI,iBAAW,IAAG,IAAG,IAAG;AAAE,eAAO,MAAK,KAAI,OAAO,eAAe,IAAG,IAAG,CAAE,OAAO,IAAG,YAAY,MAAI,cAAc,MAAI,UAAU,SAAQ,GAAE,MAAK,IAAG;AAAA;AAAI,iBAAW,IAAG,IAAG;AAAE,YAAI,KAAI,OAAO,KAAK;AAAI,YAAI,OAAO,uBAAuB;AAAE,cAAI,KAAI,OAAO,sBAAsB;AAAI,gBAAM,MAAI,GAAE,OAAQ,SAAU,IAAG;AAAE,mBAAO,OAAO,yBAAyB,IAAG,IAAG;AAAA,eAAiB,GAAE,KAAK,MAAM,IAAG;AAAA;AAAK,eAAO;AAAA;AAAI,iBAAW,IAAG;AAAE,iBAAS,KAAI,GAAG,KAAI,UAAU,QAAQ,MAAK;AAAE,cAAI,KAAI,AAAQ,UAAU,OAAlB,OAAuB,UAAU,MAAK;AAAI,eAAI,IAAI,EAAE,OAAO,KAAI,MAAI,QAAS,SAAU,IAAG;AAAE,cAAE,IAAG,IAAG,GAAE;AAAA,eAAU,OAAO,4BAA4B,OAAO,iBAAiB,IAAG,OAAO,0BAA0B,OAAM,EAAE,OAAO,KAAI,QAAS,SAAU,IAAG;AAAE,mBAAO,eAAe,IAAG,IAAG,OAAO,yBAAyB,IAAG;AAAA;AAAA;AAAU,eAAO;AAAA;AAAI,iBAAW,IAAG,IAAG;AAAE,YAAI,AAAc,OAAO,MAArB,cAA0B,AAAS,OAAT;AAAY,gBAAM,IAAI,UAAU;AAAuD,WAAE,YAAY,OAAO,OAAO,MAAK,GAAE,WAAW,CAAE,aAAa,CAAE,OAAO,IAAG,UAAU,MAAI,cAAc,SAAS,MAAK,EAAE,IAAG;AAAA;AAAK,iBAAW,IAAG;AAAE,eAAQ,KAAI,OAAO,iBAAiB,OAAO,iBAAiB,SAAU,IAAG;AAAE,iBAAO,GAAE,aAAa,OAAO,eAAe;AAAA,WAAM;AAAA;AAAK,iBAAW,IAAG,IAAG;AAAE,eAAQ,KAAI,OAAO,kBAAkB,SAAU,IAAG,IAAG;AAAE,iBAAO,GAAE,YAAY,IAAG;AAAA,WAAK,IAAG;AAAA;AAAK,iBAAW,IAAG,IAAG;AAAE,eAAO,CAAC,MAAK,AAAY,OAAO,MAAnB,YAAwB,AAAc,OAAO,MAArB,aAAyB,SAAU,IAAG;AAAE,cAAI,AAAW,OAAX;AAAc,kBAAM,IAAI,eAAe;AAA8D,iBAAO;AAAA,UAAI,MAAK;AAAA;AAAI,iBAAW,IAAG;AAAE,YAAI,KAAI,WAAY;AAAE,cAAI,AAAe,OAAO,WAAtB,eAAiC,CAAC,QAAQ;AAAW,mBAAO;AAAI,cAAI,QAAQ,UAAU;AAAM,mBAAO;AAAI,cAAI,AAAc,OAAO,SAArB;AAA4B,mBAAO;AAAI,cAAI;AAAE,mBAAO,KAAK,UAAU,SAAS,KAAK,QAAQ,UAAU,MAAM,IAAK,WAAY;AAAA,iBAAQ;AAAA,mBAAY,IAAP;AAAY,mBAAO;AAAA;AAAA;AAAU,eAAO,WAAY;AAAE,cAAI,IAAG,KAAI,EAAE;AAAI,cAAI,IAAG;AAAE,gBAAI,KAAI,EAAE,MAAM;AAAa,iBAAI,QAAQ,UAAU,IAAG,WAAW;AAAA;AAAU,iBAAI,GAAE,MAAM,MAAM;AAAY,iBAAO,EAAE,MAAM;AAAA;AAAA;AAAO,iBAAW,IAAG;AAAE,eAAO,SAAU,IAAG;AAAE,cAAI,MAAM,QAAQ;AAAI,mBAAO,EAAE;AAAA,UAAK,OAAM,SAAU,IAAG;AAAE,cAAI,AAAe,OAAO,UAAtB,eAAgC,OAAO,YAAY,OAAO;AAAI,mBAAO,MAAM,KAAK;AAAA,UAAK,OAAM,SAAU,IAAG,IAAG;AAAE,cAAI,IAAG;AAAE,gBAAI,AAAY,OAAO,MAAnB;AAAsB,qBAAO,EAAE,IAAG;AAAI,gBAAI,KAAI,OAAO,UAAU,SAAS,KAAK,IAAG,MAAM,GAAG;AAAK,mBAAO,AAAa,OAAb,YAAkB,GAAE,eAAgB,MAAI,GAAE,YAAY,OAAO,AAAU,OAAV,SAAe,AAAU,OAAV,QAAc,MAAM,KAAK,MAAK,AAAgB,OAAhB,eAAqB,2CAA2C,KAAK,MAAK,EAAE,IAAG,MAAK;AAAA;AAAA,UAAW,OAAM,WAAY;AAAE,gBAAM,IAAI,UAAU;AAAA;AAAA;AAA8I,iBAAW,IAAG,IAAG;AAAE,QAAC,CAAQ,MAAR,QAAa,KAAI,GAAE,WAAY,MAAI,GAAE;AAAS,iBAAS,KAAI,GAAG,KAAI,IAAI,MAAM,KAAI,KAAI,IAAG;AAAI,aAAE,MAAK,GAAE;AAAI,eAAO;AAAA;AAAI,iBAAW,IAAG;AAAE,eAAO,MAAM,UAAU,MAAM,QAAQ,MAAK,AAAqB,EAAE,QAAvB;AAAA;AAA4B,iBAAW,IAAG;AAAE,eAAO,AAAY,OAAO,MAAnB;AAAA;AAAuB,iBAAW,IAAG;AAAE,eAAO,AAAY,OAAO,MAAnB;AAAA;AAAuB,iBAAW,IAAG;AAAE,eAAO,AAAO,OAAP,QAAY,AAAO,OAAP,SAAY,SAAU,IAAG;AAAE,iBAAO,EAAE,OAAM,AAAS,OAAT;AAAA,UAAa,OAAM,AAAsB,EAAE,OAAxB;AAAA;AAA6B,iBAAW,IAAG;AAAE,eAAO,AAAa,GAAE,QAAf;AAAA;AAAoB,iBAAW,IAAG;AAAE,eAAO,AAAQ,MAAR;AAAA;AAAY,iBAAW,IAAG;AAAE,eAAO,CAAC,GAAE,OAAO;AAAA;AAAS,iBAAW,IAAG;AAAE,eAAO,AAAQ,MAAR,OAAY,AAAW,OAAX,SAAe,uBAAuB,kBAAkB,OAAO,UAAU,SAAS,KAAK;AAAA;AAAK,UAAI,IAAI,SAAU,IAAG;AAAE,eAAO,yBAAyB,OAAO;AAAA,SAAM,IAAI,SAAU,IAAG;AAAE,eAAO,iCAAiC,OAAO,IAAG;AAAA,SAAQ,IAAI,OAAO,UAAU,gBAAgB,IAAI,WAAY;AAAE,oBAAW,IAAG;AAAE,cAAI,KAAI;AAAM,aAAE,MAAM,KAAI,KAAK,QAAQ,IAAI,KAAK,UAAU;AAAI,cAAI,KAAI;AAAG,aAAE,QAAS,SAAU,IAAG;AAAE,gBAAI,KAAI,EAAE;AAAI,kBAAK,GAAE,QAAQ,GAAE,MAAM,KAAK,KAAI,GAAE,QAAQ,GAAE,MAAM,IAAG,MAAK,GAAE;AAAA,cAAY,KAAK,MAAM,QAAS,SAAU,IAAG;AAAE,eAAE,UAAU;AAAA;AAAA;AAAQ,eAAO,EAAE,IAAG,CAAC,CAAE,KAAK,OAAO,OAAO,SAAU,IAAG;AAAE,iBAAO,KAAK,QAAQ;AAAA,YAAQ,CAAE,KAAK,QAAQ,OAAO,WAAY;AAAE,iBAAO,KAAK;AAAA,YAAW,CAAE,KAAK,UAAU,OAAO,WAAY;AAAE,iBAAO,KAAK,UAAU,KAAK;AAAA,cAAc;AAAA;AAAO,iBAAW,IAAG;AAAE,YAAI,KAAI,MAAM,KAAI,MAAM,KAAI,MAAM,KAAI;AAAG,YAAI,EAAE,OAAM,EAAE;AAAI,eAAI,IAAG,KAAI,EAAE,KAAI,KAAI,EAAE;AAAA,aAAS;AAAE,cAAI,CAAC,EAAE,KAAK,IAAG;AAAS,kBAAM,IAAI,MAAM,SAAU,IAAG;AAAE,qBAAO,WAAW,OAAO,IAAG;AAAA,cAAsB;AAAU,cAAI,KAAI,GAAE;AAAM,cAAI,KAAI,IAAG,EAAE,KAAK,IAAG,aAAc,MAAI,GAAE,WAAW;AAAG,kBAAM,IAAI,MAAM,SAAU,IAAG;AAAE,qBAAO,6BAA6B,OAAO,IAAG;AAAA,cAAkC;AAAK,eAAI,EAAE,KAAI,KAAI,EAAE;AAAA;AAAK,eAAO,CAAE,MAAM,IAAG,IAAI,IAAG,QAAQ,IAAG,KAAK;AAAA;AAAM,iBAAW,IAAG;AAAE,eAAO,EAAE,MAAK,KAAI,GAAE,MAAM;AAAA;AAAO,iBAAW,IAAG;AAAE,eAAO,EAAE,MAAK,GAAE,KAAK,OAAO;AAAA;AAAI,UAAI,IAAI,EAAE,IAAI,CAAE,iBAAiB,OAAI,cAAc,OAAI,MAAM,IAAI,YAAY,MAAI,QAAQ,SAAU,IAAG,IAAG;AAAE,eAAO,GAAE,UAAU,GAAE,QAAQ,GAAE,MAAM,GAAE,MAAM,KAAK,IAAI,GAAE,QAAQ,GAAE,QAAQ,KAAK;AAAA,UAAO,IAAI,CAAE,gBAAgB,OAAI,gBAAgB,OAAI,oBAAoB,IAAK,IAAI,CAAE,UAAU,GAAG,WAAW,KAAI,UAAU,MAAO,IAAI,CAAE,mBAAmB,OAAI,OAAO,SAAU,IAAG,IAAG;AAAE,YAAI,KAAI,IAAI,KAAI;AAAI,eAAO,YAAW,IAAG,IAAG,IAAG;AAAE,cAAI,EAAE;AAAI,gBAAI,GAAE,KAAI;AAAE,kBAAI,KAAI,GAAE,GAAE;AAAK,kBAAI,CAAC,EAAE;AAAI;AAAQ,kBAAI,OAAM,GAAE,SAAS,KAAM,GAAE,OAAM,EAAE,OAAM,EAAE;AAAK,mBAAE,KAAK,SAAU,IAAG;AAAE,yBAAO,AAAQ,MAAR,OAAY,KAAK,SAAU,IAAG;AAAE,wBAAI,AAAY,OAAO,MAAnB;AAAsB,6BAAO;AAAG,wBAAI,KAAI,KAAI;AAAI,2BAAO,AAAO,MAAP,OAAY,IAAI,MAAK,KAAK,IAAI,OAAO;AAAA,oBAAI;AAAA,kBAAK;AAAA,uBAAc,EAAE,KAAI;AAAE,qBAAI;AAAI,yBAAS,KAAI,GAAG,KAAI,GAAE,QAAQ,KAAI,IAAG,MAAK;AAAE,qBAAE,GAAE,KAAI,IAAG,KAAI;AAAA;AAAU,mBAAE,UAAU,GAAE,IAAG,IAAG,KAAI;AAAA;AAAU,iBAAE,KAAK;AAAA,UAAK,IAAG,EAAE,MAAK,GAAE,MAAM,OAAO,IAAG,IAAI,KAAI,KAAI,GAAE;AAAA,SAAM,gBAAgB,OAAI,iBAAiB,SAAO,IAAI;AAAU,mBAAa;AAAE,YAAI,KAAI,UAAU,SAAS,KAAK,AAAW,UAAU,OAArB,SAA0B,UAAU,KAAK,GAAG,KAAI,IAAI,OAAK,KAAI,KAAK,IAAI,IAAI;AAAI,eAAO,CAAE,KAAK,SAAU,IAAG;AAAE,cAAI,KAAI,GAAE,MAAM,GAAG;AAAQ,cAAI,GAAE,IAAI;AAAI,mBAAO,GAAE,IAAI;AAAI,cAAI,KAAI,IAAI,KAAK,KAAK,KAAI,KAAI,WAAW,KAAK,MAAM,KAAI,MAAK;AAAI,iBAAO,GAAE,IAAI,IAAG,KAAI;AAAA,WAAK,OAAO,WAAY;AAAE,aAAE;AAAA;AAAA;AAAc,UAAI,IAAI,WAAY;AAAE,sBAAa;AAAE,cAAI,KAAI,UAAU,SAAS,KAAK,AAAW,UAAU,OAArB,SAA0B,UAAU,KAAK,IAAI,KAAI,GAAE,OAAO,KAAI,AAAW,OAAX,SAAe,EAAE,QAAQ;AAAG,aAAE,MAAM,KAAI,KAAK,OAAO,EAAE,IAAI,KAAK,QAAQ,IAAG,KAAK,YAAY,OAAI,KAAK;AAAA;AAAoB,eAAO,EAAE,IAAG,CAAC,CAAE,KAAK,cAAc,OAAO,WAAY;AAAE,cAAI,KAAI,UAAU,SAAS,KAAK,AAAW,UAAU,OAArB,SAA0B,UAAU,KAAK;AAAI,eAAK,OAAO;AAAA,YAAO,CAAE,KAAK,mBAAmB,OAAO,WAAY;AAAE,cAAI,KAAI,UAAU,SAAS,KAAK,AAAW,UAAU,OAArB,SAA0B,UAAU,KAAK;AAAI,eAAK,UAAU;AAAA,YAAO,CAAE,KAAK,WAAW,OAAO,WAAY;AAAE,cAAI,KAAI,MAAM,KAAI,UAAU,SAAS,KAAK,AAAW,UAAU,OAArB,SAA0B,UAAU,KAAK;AAAI,eAAK,OAAO,IAAG,KAAK,WAAW,IAAI,GAAE,QAAS,SAAU,IAAG,IAAG;AAAE,eAAE,SAAS,GAAE,MAAM;AAAA;AAAA,YAAW,CAAE,KAAK,UAAU,OAAO,WAAY;AAAE,cAAI,KAAI;AAAM,WAAC,KAAK,aAAa,KAAK,KAAK,UAAW,MAAK,YAAY,MAAI,EAAE,KAAK,KAAK,MAAM,KAAK,KAAK,QAAS,SAAU,IAAG,IAAG;AAAE,eAAE,WAAW,IAAG;AAAA,eAAS,KAAK,KAAK,QAAS,SAAU,IAAG,IAAG;AAAE,eAAE,WAAW,IAAG;AAAA,cAAQ,KAAK,KAAK;AAAA,YAAc,CAAE,KAAK,OAAO,OAAO,SAAU,IAAG;AAAE,cAAI,KAAI,KAAK;AAAQ,YAAE,MAAK,KAAK,WAAW,IAAG,MAAK,KAAK,WAAW,IAAG;AAAA,YAAQ,CAAE,KAAK,YAAY,OAAO,SAAU,IAAG;AAAE,eAAK,QAAQ,OAAO,IAAG;AAAI,mBAAS,KAAI,IAAG,KAAI,KAAK,QAAQ,KAAI,IAAG,MAAK;AAAE,iBAAK,QAAQ,IAAG,KAAK;AAAA,YAAO,CAAE,KAAK,0BAA0B,OAAO,SAAU,IAAG,IAAG;AAAE,iBAAO,GAAE,KAAK,SAAS;AAAA,YAAS,CAAE,KAAK,QAAQ,OAAO,WAAY;AAAE,iBAAO,KAAK,QAAQ;AAAA,YAAY,CAAE,KAAK,cAAc,OAAO,SAAU,IAAG,IAAG;AAAE,cAAI,EAAE,OAAM,CAAC,EAAE,KAAI;AAAE,gBAAI,KAAI,CAAE,GAAG,IAAG,GAAG,IAAG,GAAG,KAAK,KAAK,IAAI;AAAM,iBAAK,QAAQ,KAAK;AAAA;AAAA,YAAU,CAAE,KAAK,cAAc,OAAO,SAAU,IAAG,IAAG;AAAE,cAAI,KAAI,MAAM,KAAI,CAAE,GAAG,IAAG,GAAG;AAAM,eAAK,KAAK,QAAS,SAAU,IAAG,IAAG;AAAE,gBAAI,KAAI,GAAE,MAAM,IAAG,GAAE;AAAO,gBAAI,EAAE;AAAI,kBAAI,EAAE;AAAI,iBAAC,WAAY;AAAE,2BAAS,KAAI,IAAI,KAAI,CAAC,CAAE,gBAAgB,IAAI,OAAO,MAAM,GAAE,UAAS;AAAE,wBAAI,KAAI,GAAE,OAAO,KAAI,GAAE,gBAAgB,KAAI,GAAE;AAAO,wBAAI,EAAE;AAAI,0BAAI,EAAE,OAAM,CAAC,EAAE,KAAI;AAAE,4BAAI,KAAI,CAAE,GAAG,IAAG,GAAG,IAAG,GAAG,GAAE,KAAK,IAAI;AAAM,2BAAE,KAAK;AAAA;AAAU,0BAAE,OAAM,GAAE,QAAS,SAAU,IAAG,IAAG;AAAE,6BAAE,KAAK,CAAE,gBAAgB,IAAG,OAAO;AAAA;AAAA;AAAW,qBAAE,EAAE,MAAK;AAAA;AAAA,uBAAgB,CAAC,EAAE,KAAI;AAAE,oBAAI,KAAI,CAAE,GAAG,IAAG,GAAG,GAAE,KAAK,IAAI;AAAM,mBAAE,EAAE,MAAK;AAAA;AAAA;AAAA,cAAS,KAAK,QAAQ,KAAK;AAAA,YAAQ,CAAE,KAAK,UAAU,OAAO,WAAY;AAAE,iBAAO,CAAE,MAAM,KAAK,MAAM,SAAS,KAAK;AAAA,cAAiB;AAAA;AAAO,iBAAW,IAAG,IAAG;AAAE,YAAI,KAAI,UAAU,SAAS,KAAK,AAAW,UAAU,OAArB,SAA0B,UAAU,KAAK,IAAI,KAAI,GAAE,OAAO,KAAI,AAAW,OAAX,SAAe,EAAE,QAAQ,IAAG,KAAI,IAAI,EAAE,CAAE,OAAO;AAAM,eAAO,GAAE,QAAQ,GAAE,IAAI,KAAK,GAAE,WAAW,KAAI,GAAE,UAAU;AAAA;AAAI,iBAAW,IAAG;AAAE,YAAI,KAAI,UAAU,SAAS,KAAK,AAAW,UAAU,OAArB,SAA0B,UAAU,KAAK,IAAI,KAAI,GAAE,QAAQ,KAAI,AAAW,OAAX,SAAe,IAAI,IAAG,KAAI,GAAE,iBAAiB,KAAI,AAAW,OAAX,SAAe,IAAI,IAAG,KAAI,GAAE,kBAAkB,KAAI,AAAW,OAAX,SAAe,IAAI,IAAG,KAAI,GAAE,UAAU,KAAI,AAAW,OAAX,SAAe,EAAE,WAAW,IAAG,KAAI,GAAE,gBAAgB,KAAI,AAAW,OAAX,SAAe,EAAE,iBAAiB,IAAG,KAAI,KAAI,GAAE;AAAQ,YAAI;AAAG,iBAAO;AAAG,YAAI,KAAI,KAAK,IAAI,KAAI;AAAI,eAAO,KAAI,KAAI,KAAI,KAAI,KAAI,IAAI;AAAA;AAAI,mBAAa;AAAE,iBAAS,KAAI,UAAU,SAAS,KAAK,AAAW,UAAU,OAArB,SAA0B,UAAU,KAAK,IAAI,KAAI,UAAU,SAAS,KAAK,AAAW,UAAU,OAArB,SAA0B,UAAU,KAAK,EAAE,oBAAoB,KAAI,IAAI,KAAI,IAAI,KAAI,IAAI,KAAI,GAAG,KAAI,GAAE,QAAQ,KAAI,IAAG,MAAK,GAAG;AAAE,cAAI,KAAI,GAAE;AAAI,gBAAK,AAAO,OAAP,KAAW,KAAI,KAAI,MAAK,AAAO,OAAP,MAAc,OAAI,KAAI,KAAK,KAAI,KAAK,MAAK,GAAE,KAAK,CAAC,IAAG,MAAK,KAAI;AAAA;AAAM,eAAO,GAAE,KAAI,MAAM,KAAI,MAAK,MAAK,GAAE,KAAK,CAAC,IAAG,KAAI,KAAK;AAAA;AAAI,iBAAW,IAAG;AAAE,iBAAS,KAAI,IAAI,KAAI,GAAG,KAAI,GAAE,QAAQ,KAAI,IAAG,MAAK,GAAG;AAAE,cAAI,KAAI,GAAE,OAAO;AAAI,aAAE,MAAM,IAAE,OAAM,KAAK,KAAK,KAAI,KAAI;AAAA;AAAI,eAAO;AAAA;AAAI,UAAI,IAAI,WAAY;AAAE,oBAAW,IAAG;AAAE,cAAI,KAAI,MAAM,KAAI,UAAU,SAAS,KAAK,AAAW,UAAU,OAArB,SAA0B,UAAU,KAAK,IAAI,KAAI,GAAE,UAAU,KAAI,AAAW,OAAX,SAAe,EAAE,WAAW,IAAG,KAAI,GAAE,WAAW,KAAI,AAAW,OAAX,SAAe,EAAE,YAAY,IAAG,KAAI,GAAE,UAAU,KAAI,AAAW,OAAX,SAAe,EAAE,WAAW,IAAG,KAAI,GAAE,gBAAgB,KAAI,AAAW,OAAX,SAAe,EAAE,iBAAiB,IAAG,KAAI,GAAE,gBAAgB,KAAI,AAAW,OAAX,SAAe,EAAE,iBAAiB,IAAG,KAAI,GAAE,oBAAoB,KAAI,AAAW,OAAX,SAAe,EAAE,qBAAqB,IAAG,KAAI,GAAE,iBAAiB,KAAI,AAAW,OAAX,SAAe,EAAE,kBAAkB,IAAG,KAAI,GAAE,gBAAgB,KAAI,AAAW,OAAX,SAAe,EAAE,iBAAiB;AAAG,cAAI,GAAE,MAAM,KAAI,KAAK,UAAU,CAAE,UAAU,IAAG,WAAW,IAAG,UAAU,IAAG,gBAAgB,IAAG,gBAAgB,IAAG,oBAAoB,IAAG,iBAAiB,IAAG,gBAAgB,KAAK,KAAK,UAAU,KAAI,KAAI,GAAE,eAAe,KAAK,SAAS,IAAI,KAAK,QAAQ,QAAQ;AAAE,gBAAI,KAAI,SAAU,IAAG,IAAG;AAAE,iBAAE,OAAO,KAAK,CAAE,SAAS,IAAG,UAAU,EAAE,KAAI,YAAY;AAAA,eAAQ,KAAI,KAAK,QAAQ;AAAQ,gBAAI,KAAI,IAAI;AAAE,uBAAS,KAAI,GAAG,KAAI,KAAI,IAAI,KAAI,KAAI,IAAG,KAAI;AAAG,mBAAE,KAAK,QAAQ,OAAO,IAAG,KAAK,KAAI,MAAK;AAAI,kBAAI,IAAG;AAAE,oBAAI,KAAI,KAAI;AAAI,mBAAE,KAAK,QAAQ,OAAO,KAAI;AAAA;AAAA;AAAY,iBAAE,KAAK,SAAS;AAAA;AAAA;AAAO,eAAO,EAAE,IAAG,CAAC,CAAE,KAAK,YAAY,OAAO,SAAU,IAAG;AAAE,cAAI,KAAI,KAAK,SAAS,KAAI,GAAE,iBAAiB,KAAI,GAAE;AAAgB,cAAI,MAAM,MAAI,GAAE,gBAAgB,KAAK,YAAY,IAAG;AAAE,gBAAI,KAAI,CAAE,SAAS,MAAI,OAAO;AAAK,mBAAO,MAAM,IAAE,UAAU,CAAC,CAAC,GAAG,GAAE,SAAS,MAAM;AAAA;AAAI,cAAI,KAAI,KAAK,SAAS,KAAI,GAAE,UAAU,KAAI,GAAE,UAAU,KAAI,GAAE,WAAW,KAAI,GAAE,gBAAgB,KAAI,GAAE,oBAAoB,KAAI,GAAE,gBAAgB,KAAI,IAAI,KAAI,GAAG,KAAI;AAAI,eAAK,OAAO,QAAS,SAAU,IAAG;AAAE,gBAAI,KAAI,GAAE,SAAS,KAAI,GAAE,UAAU,KAAI,GAAE,YAAY,KAAI,SAAU,IAAG,IAAG,IAAG;AAAE,kBAAI,KAAI,UAAU,SAAS,KAAK,AAAW,UAAU,OAArB,SAA0B,UAAU,KAAK,IAAI,KAAI,GAAE,UAAU,KAAI,AAAW,OAAX,SAAe,EAAE,WAAW,IAAG,KAAI,GAAE,UAAU,KAAI,AAAW,OAAX,SAAe,EAAE,WAAW,IAAG,KAAI,GAAE,WAAW,KAAI,AAAW,OAAX,SAAe,EAAE,YAAY,IAAG,KAAI,GAAE,gBAAgB,KAAI,AAAW,OAAX,SAAe,EAAE,iBAAiB,IAAG,KAAI,GAAE,oBAAoB,KAAI,AAAW,OAAX,SAAe,EAAE,qBAAqB,IAAG,KAAI,GAAE,gBAAgB,KAAI,AAAW,OAAX,SAAe,EAAE,iBAAiB,IAAG,KAAI,GAAE,gBAAgB,KAAI,AAAW,OAAX,SAAe,EAAE,iBAAiB;AAAG,kBAAI,GAAE,SAAS;AAAI,sBAAM,IAAI,MAAM,EAAE;AAAM,uBAAS,IAAG,KAAI,GAAE,QAAQ,KAAI,GAAE,QAAQ,KAAI,KAAK,IAAI,GAAG,KAAK,IAAI,IAAG,MAAK,KAAI,IAAG,KAAI,IAAG,KAAI,KAAI,KAAK,IAAG,KAAI,KAAI,MAAM,MAAK,IAAK,MAAI,GAAE,QAAQ,IAAG,OAAM,MAAK;AAAE,oBAAI,KAAI,EAAE,IAAG,CAAE,iBAAiB,IAAG,kBAAkB,IAAG,UAAU,IAAG,gBAAgB;AAAM,oBAAI,KAAI,KAAK,IAAI,IAAG,KAAI,KAAI,KAAI,IAAG;AAAG,2BAAS,KAAI,GAAG,KAAI;AAAG,uBAAE,KAAI,MAAK,GAAG,MAAK;AAAA;AAAI,mBAAI;AAAI,uBAAS,KAAI,IAAI,KAAI,GAAG,KAAI,KAAI,IAAG,KAAI,KAAK,KAAI,GAAG,KAAI,GAAG,KAAI,IAAG,MAAK,GAAG;AAAE,yBAAS,KAAI,GAAG,KAAI,IAAG,KAAI,MAAI;AAAE,sBAAI,KAAI,EAAE,IAAG,CAAE,QAAQ,IAAG,iBAAiB,KAAI,IAAG,kBAAkB,IAAG,UAAU,IAAG,gBAAgB;AAAM,wBAAK,KAAI,KAAI,KAAI,KAAI,IAAG,KAAI,KAAK,MAAO,MAAI,MAAK,IAAI;AAAA;AAAK,qBAAI;AAAG,oBAAI,KAAI,KAAK,IAAI,GAAG,KAAI,KAAI,IAAI,KAAI,KAAI,KAAI,KAAK,IAAI,KAAI,IAAG,MAAK,IAAG,KAAI,MAAM,KAAI;AAAI,mBAAE,KAAI,KAAM,MAAK,MAAK;AAAG,yBAAS,KAAI,IAAG,MAAK,IAAG,MAAK,GAAG;AAAE,sBAAI,KAAI,KAAI,GAAG,KAAI,GAAE,GAAE,OAAO;AAAK,sBAAI,MAAM,IAAE,MAAK,CAAC,CAAC,CAAC,KAAI,GAAE,MAAM,IAAE,KAAI,MAAM,IAAI,KAAK,IAAG,MAAM,IAAE,OAAO,IAAE,KAAI,KAAK,GAAE,QAAO,IAAI,IAAI,GAAE,KAAI,KAAK,GAAE,MAAK,MAAM,MAAI,EAAE,IAAG,CAAE,QAAQ,IAAG,iBAAiB,IAAG,kBAAkB,IAAG,UAAU,IAAG,gBAAgB,SAAS,IAAG;AAAE,wBAAI,KAAI,IAAI,MAAI,OAAM;AAAG;AAAO,yBAAI,KAAK,IAAI,GAAG,IAAI,KAAI;AAAA;AAAA;AAAO,oBAAI,KAAI,EAAE,IAAG,CAAE,QAAQ,KAAI,GAAG,iBAAiB,IAAG,kBAAkB,IAAG,UAAU,IAAG,gBAAgB;AAAM,oBAAI,KAAI;AAAG;AAAO,qBAAI;AAAA;AAAI,kBAAI,KAAI,CAAE,SAAS,MAAK,GAAG,OAAO,KAAK,IAAI,MAAM;AAAM,kBAAI,IAAG;AAAE,oBAAI,KAAI,EAAE,IAAG;AAAI,mBAAE,SAAS,MAAM,IAAE,UAAU,MAAK,GAAE,UAAU;AAAA;AAAK,qBAAO;AAAA,cAAI,IAAG,IAAG,IAAG,CAAE,UAAU,KAAI,IAAG,UAAU,IAAG,WAAW,IAAG,gBAAgB,IAAG,oBAAoB,IAAG,gBAAgB,IAAG,gBAAgB,MAAM,KAAI,GAAE,SAAS,KAAI,GAAE,OAAO,KAAI,GAAE;AAAS,kBAAM,MAAI,OAAK,MAAK,IAAG,MAAK,MAAM,MAAI,GAAG,OAAO,EAAE,KAAI,EAAE;AAAA;AAAU,cAAI,KAAI,CAAE,SAAS,IAAG,OAAO,KAAI,KAAI,KAAK,OAAO,SAAS;AAAK,iBAAO,MAAK,MAAM,IAAE,UAAU,KAAI;AAAA,cAAS;AAAA,WAAO,IAAI,WAAY;AAAE,oBAAW,IAAG;AAAE,aAAE,MAAM,KAAI,KAAK,UAAU;AAAA;AAAI,eAAO,EAAE,IAAG,CAAC,CAAE,KAAK,UAAU,OAAO,WAAY;AAAA,aAAQ,CAAC,CAAE,KAAK,gBAAgB,OAAO,SAAU,IAAG;AAAE,iBAAO,EAAE,IAAG,KAAK;AAAA,YAAiB,CAAE,KAAK,iBAAiB,OAAO,SAAU,IAAG;AAAE,iBAAO,EAAE,IAAG,KAAK;AAAA,cAAoB;AAAA;AAAO,iBAAW,IAAG,IAAG;AAAE,YAAI,KAAI,GAAE,MAAM;AAAI,eAAO,KAAI,GAAE,KAAK;AAAA;AAAO,UAAI,IAAI,SAAU,IAAG;AAAE,UAAE,IAAG;AAAI,YAAI,KAAI,EAAE;AAAI,oBAAW,IAAG;AAAE,iBAAO,GAAE,MAAM,KAAI,GAAE,KAAK,MAAM;AAAA;AAAK,eAAO,EAAE,IAAG,CAAC,CAAE,KAAK,UAAU,OAAO,SAAU,IAAG;AAAE,cAAI,KAAI,OAAM,KAAK;AAAS,iBAAO,CAAE,SAAS,IAAG,OAAO,KAAI,IAAI,GAAG,SAAS,CAAC,GAAG,KAAK,QAAQ,SAAS;AAAA,aAAW,CAAC,CAAE,KAAK,QAAQ,KAAK,WAAY;AAAE,iBAAO;AAAA,YAAa,CAAE,KAAK,cAAc,KAAK,WAAY;AAAE,iBAAO;AAAA,YAAiB,CAAE,KAAK,eAAe,KAAK,WAAY;AAAE,iBAAO;AAAA,cAAiB;AAAA,QAAI,IAAI,IAAI,SAAU,IAAG;AAAE,UAAE,IAAG;AAAI,YAAI,KAAI,EAAE;AAAI,oBAAW,IAAG;AAAE,iBAAO,GAAE,MAAM,KAAI,GAAE,KAAK,MAAM;AAAA;AAAK,eAAO,EAAE,IAAG,CAAC,CAAE,KAAK,UAAU,OAAO,SAAU,IAAG;AAAE,cAAI,KAAI,AAAO,GAAE,QAAQ,KAAK,aAAtB;AAAgC,iBAAO,CAAE,SAAS,IAAG,OAAO,KAAI,IAAI,GAAG,SAAS,CAAC,GAAG,GAAE,SAAS;AAAA,aAAW,CAAC,CAAE,KAAK,QAAQ,KAAK,WAAY;AAAE,iBAAO;AAAA,YAAqB,CAAE,KAAK,cAAc,KAAK,WAAY;AAAE,iBAAO;AAAA,YAAiB,CAAE,KAAK,eAAe,KAAK,WAAY;AAAE,iBAAO;AAAA,cAAiB;AAAA,QAAI,IAAI,IAAI,SAAU,IAAG;AAAE,UAAE,IAAG;AAAI,YAAI,KAAI,EAAE;AAAI,oBAAW,IAAG;AAAE,iBAAO,GAAE,MAAM,KAAI,GAAE,KAAK,MAAM;AAAA;AAAK,eAAO,EAAE,IAAG,CAAC,CAAE,KAAK,UAAU,OAAO,SAAU,IAAG;AAAE,cAAI,KAAI,GAAE,WAAW,KAAK;AAAU,iBAAO,CAAE,SAAS,IAAG,OAAO,KAAI,IAAI,GAAG,SAAS,CAAC,GAAG,KAAK,QAAQ,SAAS;AAAA,aAAW,CAAC,CAAE,KAAK,QAAQ,KAAK,WAAY;AAAE,iBAAO;AAAA,YAAoB,CAAE,KAAK,cAAc,KAAK,WAAY;AAAE,iBAAO;AAAA,YAAkB,CAAE,KAAK,eAAe,KAAK,WAAY;AAAE,iBAAO;AAAA,cAAkB;AAAA,QAAI,IAAI,IAAI,SAAU,IAAG;AAAE,UAAE,IAAG;AAAI,YAAI,KAAI,EAAE;AAAI,oBAAW,IAAG;AAAE,iBAAO,GAAE,MAAM,KAAI,GAAE,KAAK,MAAM;AAAA;AAAK,eAAO,EAAE,IAAG,CAAC,CAAE,KAAK,UAAU,OAAO,SAAU,IAAG;AAAE,cAAI,KAAI,CAAC,GAAE,WAAW,KAAK;AAAU,iBAAO,CAAE,SAAS,IAAG,OAAO,KAAI,IAAI,GAAG,SAAS,CAAC,GAAG,GAAE,SAAS;AAAA,aAAW,CAAC,CAAE,KAAK,QAAQ,KAAK,WAAY;AAAE,iBAAO;AAAA,YAA4B,CAAE,KAAK,cAAc,KAAK,WAAY;AAAE,iBAAO;AAAA,YAAmB,CAAE,KAAK,eAAe,KAAK,WAAY;AAAE,iBAAO;AAAA,cAAmB;AAAA,QAAI,IAAI,IAAI,SAAU,IAAG;AAAE,UAAE,IAAG;AAAI,YAAI,KAAI,EAAE;AAAI,oBAAW,IAAG;AAAE,iBAAO,GAAE,MAAM,KAAI,GAAE,KAAK,MAAM;AAAA;AAAK,eAAO,EAAE,IAAG,CAAC,CAAE,KAAK,UAAU,OAAO,SAAU,IAAG;AAAE,cAAI,KAAI,GAAE,SAAS,KAAK;AAAU,iBAAO,CAAE,SAAS,IAAG,OAAO,KAAI,IAAI,GAAG,SAAS,CAAC,GAAE,SAAS,KAAK,QAAQ,QAAQ,GAAE,SAAS;AAAA,aAAW,CAAC,CAAE,KAAK,QAAQ,KAAK,WAAY;AAAE,iBAAO;AAAA,YAAoB,CAAE,KAAK,cAAc,KAAK,WAAY;AAAE,iBAAO;AAAA,YAAkB,CAAE,KAAK,eAAe,KAAK,WAAY;AAAE,iBAAO;AAAA,cAAkB;AAAA,QAAI,IAAI,IAAI,SAAU,IAAG;AAAE,UAAE,IAAG;AAAI,YAAI,KAAI,EAAE;AAAI,oBAAW,IAAG;AAAE,iBAAO,GAAE,MAAM,KAAI,GAAE,KAAK,MAAM;AAAA;AAAK,eAAO,EAAE,IAAG,CAAC,CAAE,KAAK,UAAU,OAAO,SAAU,IAAG;AAAE,cAAI,KAAI,CAAC,GAAE,SAAS,KAAK;AAAU,iBAAO,CAAE,SAAS,IAAG,OAAO,KAAI,IAAI,GAAG,SAAS,CAAC,GAAG,GAAE,SAAS;AAAA,aAAW,CAAC,CAAE,KAAK,QAAQ,KAAK,WAAY;AAAE,iBAAO;AAAA,YAA4B,CAAE,KAAK,cAAc,KAAK,WAAY;AAAE,iBAAO;AAAA,YAAmB,CAAE,KAAK,eAAe,KAAK,WAAY;AAAE,iBAAO;AAAA,cAAmB;AAAA,QAAI,IAAI,IAAI,SAAU,IAAG;AAAE,UAAE,IAAG;AAAI,YAAI,KAAI,EAAE;AAAI,oBAAW,IAAG;AAAE,cAAI,IAAG,KAAI,UAAU,SAAS,KAAK,AAAW,UAAU,OAArB,SAA0B,UAAU,KAAK,IAAI,KAAI,GAAE,UAAU,KAAI,AAAW,OAAX,SAAe,EAAE,WAAW,IAAG,KAAI,GAAE,WAAW,KAAI,AAAW,OAAX,SAAe,EAAE,YAAY,IAAG,KAAI,GAAE,UAAU,KAAI,AAAW,OAAX,SAAe,EAAE,WAAW,IAAG,KAAI,GAAE,gBAAgB,KAAI,AAAW,OAAX,SAAe,EAAE,iBAAiB,IAAG,KAAI,GAAE,gBAAgB,KAAI,AAAW,OAAX,SAAe,EAAE,iBAAiB,IAAG,KAAI,GAAE,oBAAoB,KAAI,AAAW,OAAX,SAAe,EAAE,qBAAqB,IAAG,KAAI,GAAE,iBAAiB,KAAI,AAAW,OAAX,SAAe,EAAE,kBAAkB,IAAG,KAAI,GAAE,gBAAgB,KAAI,AAAW,OAAX,SAAe,EAAE,iBAAiB;AAAG,iBAAO,GAAE,MAAM,KAAK,MAAI,GAAE,KAAK,MAAM,KAAI,eAAe,IAAI,EAAE,IAAG,CAAE,UAAU,IAAG,WAAW,IAAG,UAAU,IAAG,gBAAgB,IAAG,gBAAgB,IAAG,oBAAoB,IAAG,iBAAiB,IAAG,gBAAgB,MAAM;AAAA;AAAI,eAAO,EAAE,IAAG,CAAC,CAAE,KAAK,UAAU,OAAO,SAAU,IAAG;AAAE,iBAAO,KAAK,aAAa,SAAS;AAAA,aAAS,CAAC,CAAE,KAAK,QAAQ,KAAK,WAAY;AAAE,iBAAO;AAAA,YAAa,CAAE,KAAK,cAAc,KAAK,WAAY;AAAE,iBAAO;AAAA,YAAgB,CAAE,KAAK,eAAe,KAAK,WAAY;AAAE,iBAAO;AAAA,cAAgB;AAAA,QAAI,IAAI,IAAI,SAAU,IAAG;AAAE,UAAE,IAAG;AAAI,YAAI,KAAI,EAAE;AAAI,oBAAW,IAAG;AAAE,iBAAO,GAAE,MAAM,KAAI,GAAE,KAAK,MAAM;AAAA;AAAK,eAAO,EAAE,IAAG,CAAC,CAAE,KAAK,UAAU,OAAO,SAAU,IAAG;AAAE,mBAAS,IAAG,KAAI,GAAG,KAAI,IAAI,KAAI,KAAK,QAAQ,QAAS,MAAI,GAAE,QAAQ,KAAK,SAAS,OAAM;AAAI,iBAAI,KAAI,IAAG,GAAE,KAAK,CAAC,IAAG,KAAI;AAAK,cAAI,KAAI,CAAC,CAAC,GAAE;AAAQ,iBAAO,CAAE,SAAS,IAAG,OAAO,KAAI,IAAI,GAAG,SAAS;AAAA,aAAU,CAAC,CAAE,KAAK,QAAQ,KAAK,WAAY;AAAE,iBAAO;AAAA,YAAe,CAAE,KAAK,cAAc,KAAK,WAAY;AAAE,iBAAO;AAAA,YAAiB,CAAE,KAAK,eAAe,KAAK,WAAY;AAAE,iBAAO;AAAA,cAAiB;AAAA,QAAI,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,IAAI,EAAE,QAAQ,IAAI;AAAoC,iBAAW,IAAG;AAAE,YAAI,KAAI,UAAU,SAAS,KAAK,AAAW,UAAU,OAArB,SAA0B,UAAU,KAAK;AAAI,eAAO,GAAE,MAAM,KAAK,IAAK,SAAU,IAAG;AAAE,mBAAS,KAAI,GAAE,OAAO,MAAM,GAAG,OAAQ,SAAU,IAAG;AAAE,mBAAO,MAAK,CAAC,CAAC,GAAE;AAAA,cAAY,KAAI,IAAI,KAAI,GAAG,KAAI,GAAE,QAAQ,KAAI,IAAG,MAAK,GAAG;AAAE,qBAAS,KAAI,GAAE,KAAI,KAAI,OAAI,KAAI,IAAI,CAAC,MAAK,EAAE,KAAI,KAAI;AAAE,kBAAI,KAAI,EAAE,KAAI,KAAI,GAAE,aAAa;AAAI,oBAAM,IAAE,KAAK,IAAI,GAAE,IAAG,MAAK,KAAI;AAAA;AAAM,gBAAI,CAAC;AAAG,mBAAK,KAAI,IAAI,EAAE,KAAI,KAAI;AAAE,oBAAI,KAAI,EAAE,KAAI,KAAI,GAAE,cAAc;AAAI,oBAAI,IAAG;AAAE,qBAAE,KAAK,IAAI,GAAE,IAAG;AAAK;AAAA;AAAA;AAAA;AAAY,iBAAO;AAAA;AAAA;AAAQ,UAAI,IAAI,IAAI,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,IAAI,WAAY;AAAE,oBAAW,IAAG;AAAE,cAAI,KAAI,UAAU,SAAS,KAAK,AAAW,UAAU,OAArB,SAA0B,UAAU,KAAK,IAAI,KAAI,GAAE,iBAAiB,KAAI,AAAW,OAAX,SAAe,EAAE,kBAAkB,IAAG,KAAI,GAAE,gBAAgB,KAAI,AAAW,OAAX,SAAe,EAAE,iBAAiB,IAAG,KAAI,GAAE,oBAAoB,KAAI,AAAW,OAAX,SAAe,EAAE,qBAAqB,IAAG,KAAI,GAAE,gBAAgB,KAAI,AAAW,OAAX,SAAe,EAAE,iBAAiB,IAAG,KAAI,GAAE,gBAAgB,KAAI,AAAW,OAAX,SAAe,EAAE,iBAAiB,IAAG,KAAI,GAAE,UAAU,KAAI,AAAW,OAAX,SAAe,EAAE,WAAW,IAAG,KAAI,GAAE,WAAW,KAAI,AAAW,OAAX,SAAe,EAAE,YAAY,IAAG,KAAI,GAAE,UAAU,KAAI,AAAW,OAAX,SAAe,EAAE,WAAW;AAAG,aAAE,MAAM,KAAI,KAAK,QAAQ,MAAM,KAAK,UAAU,CAAE,iBAAiB,IAAG,gBAAgB,IAAG,oBAAoB,IAAG,gBAAgB,IAAG,gBAAgB,IAAG,UAAU,IAAG,WAAW,IAAG,UAAU,KAAK,KAAK,UAAU,KAAI,KAAI,GAAE,eAAe,KAAK,QAAQ,EAAE,KAAK,SAAS,KAAK;AAAA;AAAW,eAAO,EAAE,IAAG,CAAC,CAAE,KAAK,YAAY,OAAO,SAAU,IAAG;AAAE,cAAI,KAAI,KAAK;AAAO,cAAI,CAAC;AAAG,mBAAO,CAAE,SAAS,OAAI,OAAO;AAAK,cAAI,KAAI,KAAK,SAAS,KAAI,GAAE;AAAgB,eAAI,GAAE,kBAAkB,KAAI,GAAE;AAAe,mBAAS,KAAI,GAAG,KAAI,IAAI,KAAI,GAAG,KAAI,GAAG,KAAI,GAAE,QAAQ,KAAI,IAAG,MAAK,GAAG;AAAE,gBAAI,KAAI,GAAE;AAAI,eAAE,SAAS,GAAG,KAAI;AAAG,qBAAS,KAAI,GAAG,KAAI,GAAE,QAAQ,KAAI,IAAG,MAAK,GAAG;AAAE,kBAAI,KAAI,GAAE,KAAI,KAAI,GAAE,OAAO,KAAI,KAAI,GAAE,SAAS,KAAI,GAAE,SAAS,KAAI,GAAE;AAAO,kBAAI,CAAC,IAAG;AAAE,qBAAI,GAAG,KAAI,GAAG,GAAE,SAAS;AAAG;AAAA;AAAQ,kBAAI,MAAK,GAAG,MAAK,IAAG,IAAG;AAAE,oBAAI,KAAI,GAAE,YAAY;AAAM,kBAAE,IAAI,MAAK,KAAI,GAAG,OAAO,EAAE,KAAI,EAAE,OAAM,GAAE,KAAK;AAAA;AAAA;AAAO,gBAAI,IAAG;AAAE,kBAAI,KAAI,CAAE,SAAS,MAAI,OAAO,KAAI;AAAK,qBAAO,MAAM,IAAE,UAAU,KAAI;AAAA;AAAA;AAAM,iBAAO,CAAE,SAAS,OAAI,OAAO;AAAA,aAAU,CAAC,CAAE,KAAK,aAAa,OAAO,SAAU,IAAG,IAAG;AAAE,iBAAO,GAAE;AAAA,cAAyB;AAAA,WAAO,KAAK;AAAI,kBAAY,IAAG,IAAG;AAAE,iBAAS,KAAI,GAAG,KAAI,GAAG,QAAQ,KAAI,IAAG,MAAK,GAAG;AAAE,cAAI,KAAI,GAAG;AAAI,cAAI,GAAE,UAAU,IAAG;AAAI,mBAAO,IAAI,GAAE,IAAG;AAAA;AAAK,eAAO,IAAI,EAAE,IAAG;AAAA;AAAK,UAAI,KAAK,QAAQ,KAAK,OAAO,KAAK,SAAS,KAAK,QAAQ,KAAK,SAAU,IAAG;AAAE,eAAO,CAAE,EAAC,GAAE,OAAO,CAAC,GAAE;AAAA,SAAQ,KAAK,SAAU,IAAG;AAAE,eAAO,CAAC,CAAC,GAAE;AAAA,SAAO,KAAK,SAAU,IAAG;AAAE,eAAO,CAAC,EAAE,OAAM,EAAE,OAAM,CAAC,GAAG;AAAA,SAAM,KAAK,SAAU,IAAG;AAAE,eAAO,EAAE,IAAI,IAAI,OAAO,KAAK,IAAG,IAAK,SAAU,IAAG;AAAE,iBAAO,EAAE,IAAI,IAAG,GAAE;AAAA;AAAA;AAAY,kBAAY,IAAG,IAAG;AAAE,YAAI,KAAI,GAAE,iBAAiB,KAAI,AAAW,OAAX,SAAe,EAAE,kBAAkB;AAAG,WAAE,QAAS,SAAU,IAAG;AAAE,cAAI,KAAI;AAAG,aAAE,QAAQ,QAAS,SAAU,IAAG;AAAE,gBAAI,KAAI,GAAE,KAAK,KAAI,GAAE,MAAM,KAAI,GAAE,OAAO,KAAI,KAAI,GAAE,SAAS;AAAM,kBAAK,KAAK,IAAI,AAAM,OAAN,KAAW,KAAI,OAAO,UAAU,IAAI,OAAK,KAAM,MAAI,IAAI;AAAA,cAAS,GAAE,QAAQ;AAAA;AAAA;AAAQ,kBAAY,IAAG,IAAG;AAAE,YAAI,KAAI,GAAE;AAAS,WAAE,UAAU,IAAI,EAAE,OAAM,GAAE,QAAS,SAAU,IAAG;AAAE,cAAI,EAAE,GAAE,YAAY,GAAE,QAAQ,QAAQ;AAAE,gBAAI,KAAI,CAAE,SAAS,GAAE,SAAS,OAAO,GAAE;AAAS,eAAE,OAAQ,IAAE,MAAM,GAAE,IAAI,MAAM,GAAE,MAAM,MAAO,IAAE,WAAW,GAAE,MAAM,GAAE,QAAQ,KAAK;AAAA;AAAA;AAAA;AAAW,kBAAY,IAAG,IAAG;AAAE,WAAE,QAAQ,GAAE;AAAA;AAAQ,kBAAY,IAAG,IAAG;AAAE,YAAI,KAAI,UAAU,SAAS,KAAK,AAAW,UAAU,OAArB,SAA0B,UAAU,KAAK,IAAI,KAAI,GAAE,gBAAgB,KAAI,AAAW,OAAX,SAAe,EAAE,iBAAiB,IAAG,KAAI,GAAE,cAAc,KAAI,AAAW,OAAX,SAAe,EAAE,eAAe,IAAG,KAAI;AAAI,eAAO,MAAK,GAAE,KAAK,KAAK,MAAK,GAAE,KAAK,KAAK,GAAE,IAAK,SAAU,IAAG;AAAE,cAAI,KAAI,GAAE,KAAK,KAAI,CAAE,MAAM,GAAE,KAAI,UAAU;AAAK,iBAAO,GAAE,UAAU,GAAE,QAAS,SAAU,IAAG;AAAE,eAAE,IAAG;AAAA,cAAQ;AAAA;AAAA;AAAQ,UAAI,KAAK,WAAY;AAAE,oBAAW,IAAG;AAAE,cAAI,KAAI,UAAU,SAAS,KAAK,AAAW,UAAU,OAArB,SAA0B,UAAU,KAAK,IAAI,KAAI,UAAU,SAAS,IAAI,UAAU,KAAK;AAAQ,aAAE,MAAM,KAAI,KAAK,UAAU,EAAE,IAAI,GAAG,IAAI,KAAI,KAAK,QAAQ,mBAAmB,KAAK,YAAY,IAAI,EAAE,KAAK,QAAQ,OAAO,KAAK,cAAc,IAAG;AAAA;AAAK,eAAO,EAAE,IAAG,CAAC,CAAE,KAAK,iBAAiB,OAAO,SAAU,IAAG,IAAG;AAAE,cAAI,KAAK,QAAQ,IAAG,MAAK,CAAE,eAAa;AAAI,kBAAM,IAAI,MAAM;AAA2B,eAAK,WAAW,MAAK,EAAE,KAAK,QAAQ,MAAM,KAAK,OAAO,CAAE,OAAO,KAAK,QAAQ;AAAA,YAAc,CAAE,KAAK,OAAO,OAAO,SAAU,IAAG;AAAE,YAAE,OAAO,MAAK,MAAM,KAAK,KAAI,KAAK,SAAS,IAAI;AAAA,YAAS,CAAE,KAAK,UAAU,OAAO,WAAY;AAAE,mBAAS,KAAI,UAAU,SAAS,KAAK,AAAW,UAAU,OAArB,SAA0B,UAAU,KAAK,WAAY;AAAE,mBAAO;AAAA,aAAM,KAAI,IAAI,KAAI,GAAG,KAAI,KAAK,MAAM,QAAQ,KAAI,IAAG,MAAK,GAAG;AAAE,gBAAI,KAAI,KAAK,MAAM;AAAI,eAAE,IAAG,OAAO,MAAK,SAAS,KAAI,MAAK,GAAG,MAAK,GAAG,GAAE,KAAK;AAAA;AAAM,iBAAO;AAAA,YAAO,CAAE,KAAK,YAAY,OAAO,SAAU,IAAG;AAAE,eAAK,MAAM,OAAO,IAAG,IAAI,KAAK,SAAS,SAAS;AAAA,YAAQ,CAAE,KAAK,YAAY,OAAO,WAAY;AAAE,iBAAO,KAAK;AAAA,YAAc,CAAE,KAAK,UAAU,OAAO,SAAU,IAAG;AAAE,cAAI,KAAI,UAAU,SAAS,KAAK,AAAW,UAAU,OAArB,SAA0B,UAAU,KAAK,IAAI,KAAI,GAAE,OAAO,KAAI,AAAW,OAAX,SAAe,KAAK,IAAG,KAAI,KAAK,SAAS,KAAI,GAAE,gBAAgB,KAAI,GAAE,cAAc,KAAI,GAAE,YAAY,KAAI,GAAE,QAAQ,KAAI,GAAE,iBAAiB,KAAI,EAAE,MAAK,EAAE,KAAK,MAAM,MAAM,KAAK,kBAAkB,MAAK,KAAK,kBAAkB,MAAK,KAAK,eAAe;AAAI,iBAAO,GAAG,IAAG,CAAE,iBAAiB,MAAM,MAAK,GAAE,KAAK,KAAI,EAAE,OAAM,KAAI,MAAO,MAAI,GAAE,MAAM,GAAG,MAAK,GAAG,IAAG,KAAK,OAAO,CAAE,gBAAgB,IAAG,cAAc;AAAA,YAAU,CAAE,KAAK,qBAAqB,OAAO,SAAU,IAAG;AAAE,cAAI,KAAI,GAAG,IAAG,KAAK,UAAU,KAAI,KAAK,SAAS,SAAS,KAAI;AAAI,iBAAO,GAAE,QAAS,SAAU,IAAG;AAAE,gBAAI,KAAI,GAAE,GAAG,KAAI,GAAE,GAAG,KAAI,GAAE;AAAG,gBAAI,EAAE,KAAI;AAAE,kBAAI,KAAI,GAAE,SAAS,KAAI,KAAI,GAAE,SAAS,KAAI,GAAE,OAAO,KAAI,GAAE;AAAS,oBAAK,GAAE,KAAK,CAAE,MAAM,IAAG,KAAK,IAAG,SAAS,CAAC,CAAE,OAAO,IAAG,OAAO,IAAG,MAAM,IAAG,SAAS;AAAA;AAAA,cAAe;AAAA,YAAO,CAAE,KAAK,kBAAkB,OAAO,SAAU,IAAG;AAAE,cAAI,KAAI,MAAM,KAAI,SAAU,IAAG,IAAG;AAAE,gBAAI,KAAI,UAAU,SAAS,KAAK,AAAW,UAAU,OAArB,SAA0B,UAAU,KAAK,IAAI,KAAI,GAAE,MAAM,KAAI,AAAW,OAAX,UAAgB,IAAG,KAAI,YAAW,IAAG;AAAE,kBAAI,KAAI,OAAO,KAAK,KAAI,KAAI,GAAG;AAAI,kBAAI,CAAC,MAAK,GAAE,SAAS,KAAK,CAAC,GAAG;AAAI,uBAAO,GAAE,GAAG;AAAK,kBAAI,GAAG,KAAI;AAAE,oBAAI,KAAI,KAAI,GAAE,MAAM,GAAE,IAAI,KAAI,KAAI,GAAE,MAAM,GAAE;AAAI,oBAAI,CAAC,EAAE;AAAI,wBAAM,IAAI,MAAM,EAAE;AAAK,oBAAI,KAAI,CAAE,OAAO,EAAE,KAAI,SAAS;AAAK,uBAAO,MAAM,IAAE,WAAW,GAAG,IAAG,MAAK;AAAA;AAAI,kBAAI,KAAI,CAAE,UAAU,IAAI,UAAU,GAAE;AAAM,qBAAO,GAAE,QAAS,SAAU,IAAG;AAAE,oBAAI,KAAI,GAAE;AAAI,kBAAE,OAAM,GAAE,QAAS,SAAU,IAAG;AAAE,qBAAE,SAAS,KAAK,GAAE;AAAA;AAAA,kBAAa;AAAA;AAAK,mBAAO,GAAG,OAAO,MAAI,GAAG,MAAK,GAAE;AAAA,YAAK,IAAG,KAAK,UAAU,KAAI,KAAK,SAAS,SAAS,KAAI,IAAI,KAAI;AAAI,iBAAO,GAAE,QAAS,SAAU,IAAG;AAAE,gBAAI,KAAI,GAAE,GAAG,KAAI,GAAE;AAAG,gBAAI,EAAE,KAAI;AAAE,kBAAI,KAAI,YAAW,IAAG,IAAG,IAAG;AAAE,oBAAI,CAAC,GAAE,UAAU;AAAE,sBAAI,KAAI,GAAE,OAAO,KAAI,GAAE,UAAU,KAAI,GAAE,aAAa,CAAE,KAAK,GAAE,UAAU,IAAI,KAAI,OAAO,GAAE,SAAS,uBAAuB,IAAG,KAAI,UAAU;AAAM,yBAAO,MAAK,GAAE,SAAS,CAAC,CAAE,KAAK,IAAG,MAAM,IAAG,SAAS,OAAO;AAAA;AAAK,wBAAQ,GAAE;AAAA,uBAAiB;AAAI,6BAAS,KAAI,IAAI,KAAI,GAAG,KAAI,GAAE,SAAS,QAAQ,KAAI,IAAG,MAAK,GAAG;AAAE,0BAAI,KAAI,GAAE,GAAE,SAAS,KAAI,IAAG;AAAI,0BAAI,CAAC,GAAE;AAAQ,+BAAO;AAAI,yBAAE,KAAK,MAAM,IAAG,EAAE;AAAA;AAAM,2BAAO;AAAA,uBAAQ;AAAI,6BAAS,KAAI,IAAI,KAAI,GAAG,KAAI,GAAE,SAAS,QAAQ,KAAI,IAAG,MAAK,GAAG;AAAE,0BAAI,KAAI,GAAE,GAAE,SAAS,KAAI,IAAG;AAAI,0BAAI,GAAE,QAAQ;AAAE,2BAAE,KAAK,MAAM,IAAG,EAAE;AAAK;AAAA;AAAA;AAAU,2BAAO;AAAA;AAAA,gBAAM,IAAG,IAAG;AAAI,iBAAE,UAAW,IAAE,OAAO,IAAE,MAAK,CAAE,KAAK,IAAG,MAAM,IAAG,SAAS,KAAM,GAAE,KAAK,GAAE,OAAM,GAAE,QAAS,SAAU,IAAG;AAAE,oBAAI,IAAG,KAAI,GAAE;AAAS,gBAAC,MAAI,GAAE,IAAG,SAAS,KAAK,MAAM,IAAG,EAAE;AAAA;AAAA;AAAA,cAAgB;AAAA,YAAO,CAAE,KAAK,qBAAqB,OAAO,SAAU,IAAG;AAAE,cAAI,KAAI,MAAM,KAAI,GAAG,IAAG,KAAK,UAAU,KAAI,KAAK,UAAU,KAAI,GAAE,MAAM,KAAI,GAAE,SAAS,KAAI;AAAI,iBAAO,GAAE,QAAS,SAAU,IAAG;AAAE,gBAAI,KAAI,GAAE,GAAG,KAAI,GAAE;AAAG,gBAAI,EAAE,KAAI;AAAE,kBAAI,KAAI;AAAI,iBAAE,QAAS,SAAU,IAAG,IAAG;AAAE,mBAAE,KAAK,MAAM,IAAG,EAAE,GAAE,aAAa,CAAE,KAAK,IAAG,OAAO,GAAE,KAAI,UAAU;AAAA,kBAAY,GAAE,UAAU,GAAE,KAAK,CAAE,KAAK,IAAG,MAAM,IAAG,SAAS;AAAA;AAAA,cAAY;AAAA,YAAO,CAAE,KAAK,gBAAgB,OAAO,SAAU,IAAG;AAAE,cAAI,KAAI,GAAE,KAAK,KAAI,GAAE,OAAO,KAAI,GAAE;AAAU,cAAI,CAAC,EAAE;AAAI,mBAAO;AAAI,cAAI,KAAI;AAAI,cAAI,EAAE;AAAI,eAAE,QAAS,SAAU,IAAG;AAAE,kBAAI,KAAI,GAAE,GAAG,KAAI,GAAE,GAAG,KAAI,GAAE;AAAG,kBAAI,EAAE,KAAI;AAAE,oBAAI,KAAI,GAAE,SAAS,KAAI,KAAI,GAAE,SAAS,KAAI,GAAE,OAAO,KAAI,GAAE;AAAS,sBAAK,GAAE,KAAK,CAAE,OAAO,IAAG,KAAK,IAAG,OAAO,IAAG,KAAK,IAAG,MAAM,IAAG,SAAS;AAAA;AAAA;AAAA,eAAiB;AAAE,gBAAI,KAAI,GAAE,GAAG,KAAI,GAAE,GAAG,KAAI,GAAE,SAAS,KAAI,KAAI,GAAE,SAAS,KAAI,GAAE,OAAO,KAAI,GAAE;AAAS,kBAAK,GAAE,KAAK,CAAE,OAAO,IAAG,KAAK,IAAG,OAAO,IAAG,MAAM,IAAG,SAAS;AAAA;AAAO,iBAAO;AAAA,cAAS;AAAA;AAAO,aAAO,GAAG,UAAU,SAAS,GAAG,cAAc,GAAG,GAAG,aAAa,SAAU,IAAG;AAAE,YAAI,KAAI,UAAU,SAAS,KAAK,AAAW,UAAU,OAArB,SAA0B,UAAU,KAAK,IAAI,KAAI,GAAE,OAAO,KAAI,AAAW,OAAX,SAAe,EAAE,QAAQ,IAAG,KAAI,GAAE,MAAM,KAAI,GAAE,SAAS,KAAI,IAAI,EAAE,CAAE,OAAO;AAAM,eAAO,GAAE,QAAQ,KAAI,GAAE,gBAAgB,KAAI;AAAA,SAAK,GAAG,SAAS,GAAG,WAAY;AAAE,WAAG,KAAK,MAAM,IAAI;AAAA,QAAa,IAAI;AAAA,OAAM,AAAY,OAAO,WAAnB,YAA8B,AAAe,OAAO,UAAtB,cAA+B,OAAO,UAAU,MAAM,AAAc,OAAO,UAArB,cAA+B,OAAO,MAAM,OAAO,KAAM,KAAI,KAAK,MAAM,OAAO;AAAA;;;ACU1o2B,0BAAiB;;;ACbjB,iCAAwC;AAAA,IAOpC,QAAQ;AAAA,IAOR,SAAS;AAAA,IAUT,cAAc;AAAA,IAOd,UAAU;AAAA,IAEb,YAAY,OAAO,QAAQ,aAAa,UAAU,OAAO;AACxD,WAAK,QAAQ;AACb,WAAK,SAAS;AACd,WAAK,cAAc;AACb,WAAK,UAAU;AAAA;AAAA,IAGnB,OAAO,MAAM;AACT,aAAO,KAAK,UAAU,KAAK,SACvB,KAAK,WAAW,KAAK,UACrB,KAAK,gBAAgB,KAAK;AAAA;AAAA;AA3CtC,MAAO,sCAAP;;;ACOA,sBAA6B;AAAA,IAMzB,cAAc;AAEV,WAAK,QAAQ;AAEb,UAAI,AAAgB,OAAQ,YAAxB,aAAkC;AAClC,aAAK,QAAQ,OAAO;AAAA,aACjB;AACH,aAAK,QAAQ,QAAQ,QAAQ;AAAA;AAAA;AAAA,UAU/B,IAAI,YAAY;AAClB,UAAI,AAAgB,OAAQ,YAAxB,aAAkC;AAClC,cAAM,OAAO,OAAO,KAAK;AACzB,aAAK,QAAQ,SAAO,KAAK,MAAM,QAAQ,KAAK,KAAK,UAAU,WAAW;AAAA,aACnE;AACH,cAAM,KAAK,MAAM,IAAI;AAAA;AAAA;AAAA,UAavB,IAAI,KAAK;AACX,UAAI,AAAgB,OAAQ,YAAxB,aAAkC;AAClC,YAAI,YAAY;AAChB,YAAI,OAAO,KAAK,MAAM,QAAQ;AAC9B,YAAI,CAAE,MAAM;AACR,iBAAO;AAAA;AAEX,YAAI,aAAa;AACjB,YAAI;AACA,uBAAa,KAAK,MAAM,KAAK,MAAM,QAAQ;AAAA,iBACtC,GAAP;AACE,uBAAa;AAAA;AAEjB,kBAAU,OAAO;AACjB,eAAO;AAAA,aACJ;AACH,eAAO,MAAM,KAAK,MAAM,IAAI;AAAA;AAAA;AAAA;AAzDxC,MAAO,wBAAP;;;ACVA,yBAAgC;AAAA,IAE5B,cAAc;AAGV,WAAK,SAAS;AACd,WAAK,QAAQ,IAAI;AACjB,WAAK,YAAY;AAIjB,WAAK,QAAQ;AAAA;AAAA,UAGX,kBAAkB;AACpB,cAAQ,IAAI;AACZ,UAAI,gBAAgB;AACpB,WAAK,aAAa,mBAAmB,WAAW,KAAK;AAGrD,YAAM,sBAAsB,SAAS,eAAe;AACpD,UAAI,qBAAqB;AACrB,cAAM,sBAAsB,oBAAoB,UAAU,MAAM,mCAAmC;AACnG,cAAM,iBAAgB,KAAK,MAAM;AACjC,cAAM,eAAe;AACrB,qBAAa,KAAK,cAAc;AAChC,cAAM,KAAK,MAAM,IAAI;AACrB,aAAK,UAAU,eAAc;AAC7B,aAAK,UAAU,KAAK,UAAU,eAAc;AAC5C,aAAK,WAAW,eAAc;AAE9B,aAAK,iBAAiB;AACtB,aAAK,SAAS;AACd;AAAA;AAKJ,sBAAgB,MAAM,KAAK,MAAM,IAAI,KAAK;AAC1C,UAAI,iBACG,OAAO,KAAK,eAAe,WAAW,KACtC,cAAc,KAAK,eACnB,AAAa,OAAO,cAAc,KAAK,gBAAvC,UAAqD;AAExD,wBAAgB,cAAc,KAAK;AACnC,aAAK,UAAU,cAAc;AAC7B,aAAK,UAAU,KAAK,UAAU,cAAc;AAC5C,aAAK,WAAW,cAAc;AAE9B,aAAK,iBAAiB;AACtB,aAAK,SAAS;AACd;AAAA;AAIJ,UAAI,WAAW,KAAK,YAAY;AAC5B,aAAK,UAAU,WAAW,KAAK;AAE/B,aAAK,UAAU,KAAK,UAAU;AAC9B,aAAK,SAAS;AACd;AAAA;AAGJ,cAAQ,IAAI;AAAA;AAAA,UAKV,oBAAoB;AACtB,cAAQ,IAAI;AACZ,UAAI,CAAE,KAAK,QAAQ;AACf,gBAAQ,IAAI;AACZ,aAAK,YAAY;AACjB;AAAA;AAGJ,WAAK,YAAY,MAAM,KAAK;AAC5B,cAAQ,IAAI,2BAA2B,KAAK;AAAA;AAAA,IAGhD,eAAe;AACX,aAAO,SAAS,KAAK,UAAU,SAAS,gBACpC,SAAS,KAAK,UAAU,SAAS;AAAA;AAAA,UAGnC,iBAAiB,eAAe;AAClC,UAAI,eAAe,SAAS,CAAE,KAAK,gBAAgB;AAE/C,aAAK,WAAW;AAChB,sBAAc,QAAQ;AACtB,cAAM,eAAe;AACrB,qBAAa,KAAK,cAAc;AAChC,cAAM,KAAK,MAAM,IAAI;AAAA;AAAA;AAAA,IAI7B,gBAAgB,MAAM;AAClB,YAAM,SAAS,IAAI;AAEnB,aAAO,KAAK,MAAM,QAAQ,cAAY;AAElC,YAAI,MAAM,QAAQ,KAAK,YAAY;AAC/B,gBAAM,gBAAgB,WAAW;AACjC,eAAK,UAAU,QAAS,UAAQ,OAAO,OAAO,eAAe;AAAA,eAC1D;AACH,iBAAO,OAAO,UAAU,KAAK;AAAA;AAAA;AAIrC,aAAO,OAAO;AAAA;AAAA,IAGlB,WAAW;AACP,UAAI,KAAK,UAAU;AACf,eAAO,CAAC,WAAW,UAAU,SAAS,WAAW;AAAA,aAC9C;AACH,eAAO,CAAC;AAAA;AAAA;AAAA,UAIV,eAAe;AAEjB,UAAI,AAAc,KAAK,MAAM,kBAAzB,QAAwC;AACxC,eAAO,KAAK,MAAM;AAAA;AAItB,YAAM,WAAW,MAAM,KAAK,IAAI;AAGhC,YAAM,SAAS,MAAM,SAAS;AAG9B,WAAK,MAAM,eAAe;AAE1B,aAAO;AAAA;AAAA,UAGL,SAAS,cAAc,WAAW,OAAO;AAE3C,YAAM,WAAY,SAAS,YAAY;AACvC,UAAI,AAAc,KAAK,MAAM,cAAzB,QAAoC;AACpC,eAAO,KAAK,MAAM;AAAA;AAItB,YAAM,WAAW,MAAM,KAAK,IAExB,UACA;AAAA,QACI,QAAQ;AAAA,QACR,UAAU;AAAA,QAEV,MAAM;AAAA,QACN,SAAS;AAAA;AAKjB,YAAM,SAAS,MAAM,SAAS;AAG9B,WAAK,MAAM,YAAY;AAEvB,aAAO;AAAA;AAAA,UASL,cAAc,QAAQ;AAExB,UAAI,AAAc,KAAK,MAAM,UAAU,YAAnC,QAA4C;AAC5C,eAAO,KAAK,MAAM,UAAU;AAAA;AAGhC,YAAM,OAAO;AAAA,QACT,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,MAAM;AAAA,QACN,OAAO;AAAA,QACP,aAAa;AAAA;AAGjB,YAAM,WAAW,MAAM,MAAM,GAAG,WAAW,KAAK,yBAAyB,sBAAsB;AAE/F,WAAK,MAAM,UAAU,UAAU;AAE/B,aAAO,UAAU,WAAW;AAAA;AAAA,UAG1B,WAAW,cAAc;AAE3B,UAAI,AAAc,KAAK,MAAM,aAAa,kBAAtC,QAAqD;AACrD,eAAO,KAAK,MAAM,aAAa;AAAA;AAGnC,UAAI,iBAAiB;AAErB,UAAI,cAAc;AACd,uBAAe,SAAS;AAAA;AAI5B,YAAM,WAAW,MAAM,KAAK,IACxB,WACA;AAIJ,YAAM,SAAS,MAAM,SAAS;AAG9B,WAAK,MAAM,aAAa,gBAAgB;AAExC,aAAO;AAAA;AAAA,UAGL,SAAS,cAAc;AAEzB,UAAI,AAAc,KAAK,MAAM,WAAW,kBAApC,QAAmD;AACnD,eAAO,KAAK,MAAM,WAAW;AAAA;AAIjC,YAAM,WAAW,MAAM,KAAK,IACxB,SACA;AAAA,QACI,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,SAAS;AAAA;AAKjB,YAAM,SAAS,MAAM,SAAS;AAG9B,WAAK,MAAM,WAAW,gBAAgB;AAEtC,aAAO;AAAA;AAAA,UAGL,IAAI,MAAM,OAAO,IAAI;AACvB,YAAM,OAAO;AAAA,QACT,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,MAAM;AAAA,QACN,OAAO;AAAA,QACP,aAAa;AAAA;AAIjB,UAAI,KAAK,UAAU;AACf,aAAK,WAAW,KAAK;AAAA;AAGzB,YAAM,SAAS,KAAK,gBAAgB;AAEpC,YAAM,WAAW,MAAM,MAAM,GAAG,KAAK,UAAU,SAAS,UAAU;AAElE,UAAI,SAAS,SAAS,OAAO,SAAS,UAAU,KAAK;AACjD,mBAAW,WAAW,kBAAkB,kBAAkB;AAAA;AAG9D,aAAO;AAAA;AAAA;AA5Qf,MAAO,4BAAP;;;ACFA,0BAAiC;AAAA,IAM7B;AAAA,IAMA;AAAA,IAOA,aAAa;AAAA,IAQb,YAAY,OAAO,KAAK;AACpB,WAAK,QAAQ;AACb,WAAK,MAAM;AAAA;AAAA,IASf,aAAa,MAAM,OAAO;AACtB,WAAK,WAAW,KAAK;AAAA,QACjB;AAAA,QACA;AAAA;AAAA;AAAA;AAzCZ,MAAO,6BAAP;;;ACEA,0BAAiC;AAAA,IAM7B,QAAQ;AAAA,IAQR,UAAU;AAAA,IAOV,MAAM;AAAA,IASN,eAAe;AAAA;AA9BnB,MAAO,6BAAP;;;ACAA,yBAAgC;AAAA,IAM5B,UAAU;AAAA,IAOV,cAAc;AAAA,IAed;AAAA,IAOA,uBAAuB;AAAA,IAUvB,YAAY,SAAS,aAAa,gBAAgB,uBAAuB,MAAM;AAC3E,WAAK,UAAU;AACf,WAAK,cAAc;AACnB,WAAK,iBAAiB;AACtB,WAAK,uBAAuB;AAAA;AAAA;AAjDpC,MAAO,4BAAP;;;ANsBA,gCAAuC;AAAA,IAEtC,YAAY,aAAa,SAAS;AAEjC,cAAQ,IAAI;AAEN,WAAK,UAAU;AAGf,WAAK,iBAAqD,SAAS,eAAe;AAElF,WAAK,sBAAqD,SAAS,eAAe;AAElF,WAAK,sBAAuD,SAAS,eAAe;AAEpF,WAAK,+BAA8D,SAAS,eAAe;AAE3F,WAAK,sBAAuD,SAAS,eAAe;AAEpF,WAAK,iCAAgE,SAAS,eAAe;AAE7F,WAAK,uBAAsD,SAAS,eAAe;AAEnF,WAAK,6BAA4D,SAAS,eAAe;AAEzF,WAAK,iCAAiE,SAAS,eAAe;AAE9F,WAAK,uBAAsD,SAAS,eAAe;AAInF,UAAI,WAAW,WAAW,kBAAkB;AACxC,aAAK,kBAAkB;AAAA;AAM3B,WAAK,kBAAkB,SAAS,eAAe;AAE/C,WAAK,cAAc;AACnB,UAAI,KAAK,iBAAiB;AACtB,aAAK,cAAc,KAAK,gBAAgB,cAAc,KAAK;AAAA;AAIrE,WAAK,cAAc;AAGnB,WAAK,oBAAoB;AACzB,WAAK,qBAAqB;AACpB,WAAK,yBAAyB;AAG9B,WAAK,aAAa;AAGlB,WAAK,eAAe;AAIpB,WAAK,YAAY;AAGjB,WAAK;AAGX,WAAK,eAAe,KAAK,aAAa;AAChC,WAAK,gBAAgB;AACrB,WAAK,kBAAkB;AAG7B,WAAK;AAGC,WAAK,aAAa;AAClB,WAAK;AAEX,WAAK,qBAAqB;AAC1B,WAAK,cAAc;AAEnB,UAAI,OAAQ,8BAAU,YAAY;AACjC;AAAA;AAGD,WAAK,qBAAqB;AAAA,QACzB,MAAM,CAAC;AAAA;AAGR,WAAK,cAAc,IAAI,0BAAK,KAAK,cAAc,KAAK;AAEpD,eAAS,iBAAiB,WAAW,OAAK,KAAK,gBAAgB;AAE/D,WAAK,eAAe,iBAAiB,SAAS,OAAK;AAClD,aAAK,yBAAyB;AACrB,aAAK,qBAAqB;AAAA;AAG9B,WAAK,oBAAoB,iBAAiB,aAAa,OAAK;AACxD,aAAK,eAAe,EAAE;AAAA;AAAA;AAAA,IAI9B,WAAW,OAAO;AACd,UAAI,MAAM,IAAI,YAAY,gBAAgB,OAAO;AACjD,aAAO,IAAI,gBAAgB;AAAA;AAAA,IAG/B,QAAQ;AACJ,aAAO,UAAU,SAAS,WAAW;AAAA;AAAA,IAGzC,YAAY,GAAG;AACX,aAAO,KAAK,UAAU,EAAE,UAAU,EAAE;AAAA;AAAA,IAGxC,eAAe;AACX,aAAO,KAAK,eAAe;AAAA;AAAA,IAQ/B,oBAAoB;AAChB,WAAK,eAAe;AACpB,WAAK,YAAY;AAEvB,WAAK,YAAY,QAAQ,UAAQ;AAChC,cAAM,KAAK,SAAS,cAAc;AAClC,cAAM,IAAI,SAAS,cAAc;AACjC,WAAG,YAAY;AACf,UAAE,OAAO,KAAK;AACd,YAAI,QAAQ,KAAK;AACjB,YAAI,KAAK,aAAa;AACrB,kBAAQ,KAAK,cAAc,OAAO;AAAA;AAEnC,UAAE,YAAY;AACL,aAAK,mBAAmB;AAAA;AAAA;AAAA,IAMhC,mBAAmB,UAAU;AACzB,WAAK,aAAa,KAAK;AAEvB,YAAM,OAAO,SAAS,cAAc;AACpC,UAAI,MAAM;AACN,aAAK,UAAU,KAAK,QAAQ;AAAA;AAAA;AAAA,IAIpC,kBAAkB,KAAK;AACnB,aAAO,QAAQ,KAAK,UAAU;AAAA;AAAA,IAQlC,gBAAgB,cAAc;AAC1B,WAAK,eAAe;AACpB,WAAK,YAAY;AACjB,WAAK,mBAAmB,cAAc;AAAA;AAAA,IAY1C,mBAAmB,cAAc,eAAe,MAAM;AAClD,cAAQ,IAAI;AAEZ,UAAI,aAAa,SAAS,GAAG;AACzB,qBAAa,QAAQ,KAAK,WAAW,KAAK;AAAA;AAG9C,UAAI,cAAc;AAEd,aAAK,cAAc,IAAI,0BAAK,KAAK,cAAc,KAAK;AACpD,aAAK,eAAe,KAAK,YAAY,OAAO,KAAK,oBAAoB,OAAO,IAAI,OAAK,EAAE;AAAA;AAG3F,WAAK;AAAA;AAAA,IAQT,WAAW,MAAM;AACb,YAAM,YAAY,KAAK;AAEvB,YAAM,WAAW,KAAK;AACtB,YAAM,UAAU,KAAK;AAKrB,UAAI,KAAK,kBAAkB,UAAU;AACjC,gBAAQ,IAAI;AACZ;AAAA;AAGJ,UAAI,QAAQ;AAEZ,UAAI,UAAU;AACV,cAAM,eAAe,WAAW,WAAW,UAAU,YAAY,WAAW,WAAW,UAAU,UAAU,OAAO;AAClH,iBAAS,KAAK;AAAA;AAGlB,YAAM,KAAK,SAAS,cAAc;AAClC,YAAM,IAAI,SAAS,cAAc;AACjC,UAAI,UAAU;AAGd,UAAI,KAAK,aAAa,SAAS,GAAG;AAG9B,kBAAU,SAAS,cAAc;AACjC,cAAM,eAAe,SAAS,cAAc;AAC5C,cAAM,eAAe,SAAS,cAAc;AAC5C,gBAAQ,UAAU,IAAI;AACtB,qBAAa,UAAU,IAAI;AAE3B,qBAAa,cAAc,KAAK,WAAW;AAC3C,qBAAa,UAAU,IAAI;AAC3B,gBAAQ,YAAY;AAEpB,iBAAS,IAAI,GAAG,IAAI,KAAK,aAAa,QAAQ,KAAK;AAC/C,gBAAM,cAAc,KAAK,aAAa;AAEtC,gBAAM,kBAAkB,SAAS,cAAc;AAC/C,gBAAM,cAAc,SAAS,cAAc;AAC3C,sBAAY,YAAY,YAAY;AACpC,sBAAY,OAAO,YAAY;AAC/B,mBAAS,KAAI,GAAG,KAAI,YAAY,WAAW,QAAQ,MAAK;AACpD,wBAAY,aACR,YAAY,WAAW,IAAG,MAC1B,YAAY,WAAW,IAAG;AAAA;AAGlC,0BAAgB,YAAY;AAC5B,uBAAa,YAAY;AAAA;AAI7B,gBAAQ,YAAY;AAEpB,WAAG,UAAU,IAAI;AAAA;AAGrB,QAAE,OAAO;AACT,QAAE,YAAY;AAEd,SAAG,YAAY;AACf,UAAI,YAAY,MAAM;AAClB,WAAG,YAAY;AAAA;AAGnB,WAAK,mBAAmB;AAAA;AAAA,UAStB,gBAAgB,GAAG;AAC3B,UAAI,KAAK,oBAAoB,IAAI;AACvB,UAAE;AACF,UAAE;AACX,YAAI,KAAK,gBAAgB;AACxB,eAAK;AAAA,eACC;AACN,eAAK;AAAA;AAEG;AAAA;AAGV,UAAI,EAAE,SAAS,YAAY,KAAK,gBAAgB;AAC/C,YAAI,KAAK,iBAAgB;AACZ,eAAK;AAAA,mBACE,KAAK,gBAAgB;AAC5B,eAAK;AAAA,eACF;AACH,eAAK;AAAA;AAET;AAAA;AAGJ,UAAI,KAAK,gBAAgB;AACrB,cAAM,KAAK,eAAe;AAAA;AAAA;AAAA,IAIrC,oBAAoB,UAAU;AAG7B,YAAM,cAAc,KAAK,QAAQ,aAAa,OAC7C,CAAC,YAAY,UAAU;AACtB,YAAI,YAAY;AACf,iBAAO;AAAA;AAEI,eAAS,EAAC,UAAU,SAAS,WAAW,UAAY,MAAM,SAAS,SAAS,YACpE,MAAM,QAAQ,SAAS,UACvB,MAAM,UAAU,SAAS,YACzB,MAAM,SAAS,SAAS,WAExB,UAAS,SAAS,QAAQ,MAAM,IAAI,iBAC/B,MAAM,QAAQ,OAAO,SAAS,KAAK,kBAAkB;AAAA,SAEnE;AACb,aAAO;AAAA;AAAA,IAML,2BAA2B,QAAQ;AAE/B,UAAI,KAAK,gBAAgB;AACrB;AAAA;AAKJ,UAAI,gBAAgB,KAAK,oBAAoB;AAC7C,UAAI,OAAO,WAAW,GAAG;AACrB,yBAAiB;AAAA;AAErB,UAAI,WAAW,aAAa;AACxB,wBAAgB,cAAc,MAAM,GAAG;AAAA;AAG3C,UAAI,KAAK,UAAU,gBAAgB;AAC/B,aAAK,+BAA+B,YAAY,cAAc;AAC9D,aAAK,2BAA2B,UAAU,IAAI;AAAA,aAC3C;AACH,aAAK;AAAA;AAAA;AAAA,IAIb,0BAA0B;AACtB,WAAK,2BAA2B,UAAU,OAAO;AAAA;AAAA,UAG/C,kCAAkC;AAEpC,UAAI,CAAE,KAAK,gBAAgB;AACvB,aAAK,kBAAkB;AACvB,cAAM,KAAK;AACX;AAAA;AAOJ,mBAAa,KAAK;AAElB,WAAK,kBAAkB,WAAW,iBAAkB;AAEhD,aAAK,kBAAkB;AAGvB,cAAM,KAAK;AAAA,QACb,KAAK,OAAO;AAAA;AAAA,IASlB,UAAU,aAAa;AACnB,aAAO,OAAO,KAAK,WAAW,WAAW,aAAa,SAAS;AAAA;AAAA,IAQnE,kBAAkB,MAAM;AACpB,WAAK,qBAAqB,UAAU,IAAI;AACxC,WAAK,qBAAqB,YAAY;AAAA;AAAA,IAM1C,oBAAoB;AAChB,WAAK,qBAAqB,UAAU,OAAO;AAAA;AAAA,UASzC,eAAe,GAAG;AAC1B,UAAI,EAAE,SAAS,eAAe,KAAK,gBAAgB;AAClD,UAAE;AACF,aAAK;AACL;AAAA;AAED,UAAI,EAAE,SAAS,aAAa,KAAK,gBAAgB;AAChD,UAAE;AACF,aAAK;AACL;AAAA;AAED,UAAI,EAAE,SAAS,WAAW,KAAK,gBAAgB;AACrC,UAAE;AACF,aAAK,SAAS,KAAK,YAAY;AAC/B;AAAA;AAMJ,UAAI,KAAK,iBAAiB;AACtB;AAAA;AAMJ,WAAK,2BAA2B,EAAE;AAKlC,UAAI,CAAE,KAAK,kBAAmB,GAAE,SAAS,SAAS,EAAE,QAAQ,MAAM;AAC9D,gBAAQ,IAAI;AACZ,YAAI,aAAa,KAAK,oBAAoB;AAC1C,YAAI,KAAK,UAAU,aAAa;AAC5B,kBAAQ,IAAI,uBAAuB;AACnC,YAAE;AAEF,gBAAM,KAAK,gBACP,WAAW,WAAW,YAAY;AACtC;AAAA;AAAA;AAOR,UAAI,KAAK,kBAAkB,EAAE,SAAS,eAAe,KAAK,oBAAoB,UAAU,IAAI;AACxF,UAAE;AACF,aAAK;AACL;AAAA;AAGV,YAAM,KAAK;AAAA;AAAA,UAQH,gBAAgB,YAAY;AAC9B,cAAQ,IAAI,sCAAsC,WAAW;AAC7D,WAAK;AAEL,WAAK,cAAc;AACnB,WAAK,eAAe;AACpB,WAAK,YAAY;AAGjB,WAAK;AAEL,WAAK,aAAa;AAClB,WAAK,oBAAoB,QAAQ;AACjC,WAAK,iBAAiB,WAAW;AACjC,WAAK;AACL,WAAK;AAEL,UAAI,WAAW,yBAAyB,MAAM;AAC1C,aAAK,oBAAoB,UAAU,IAAI;AACvC,cAAM,UAAU,MAAM,WAAW;AACjC,aAAK,gBAAgB;AAErB,aAAK,oBAAoB,UAAU,OAAO;AAAA;AAAA;AAAA,IAOlD,kBAAkB;AACd,YAAM,aAAa,KAAK;AAExB,WAAK,aAAa;AAClB,WAAK;AACL,WAAK;AACL,WAAK,oBAAoB,QAAQ,WAAW;AAC5C,WAAK,2BAA2B;AAChC,WAAK;AAAA;AAAA,IAOT,oBAAoB;AAChB,WAAK,oBAAoB,KAAK;AAC9B,WAAK,qBAAqB,KAAK;AAC/B,WAAK,yBAAyB,KAAK;AAAA;AAAA,IAMvC,qBAAqB;AACjB,WAAK,cAAc,KAAK;AACxB,WAAK,eAAe,KAAK;AACzB,WAAK,YAAY,KAAK;AAAA;AAAA,IAQ1B,iBAAiB,OAAO;AACpB,WAAK,qBAAqB,UAAU,IAAI;AACxC,WAAK,qBAAqB,YAAY;AAAA;AAAA,IAM1C,sBAAsB;AAClB,WAAK,qBAAqB,UAAU,OAAO;AAAA;AAAA,IAG/C,gBAAgB;AACZ,aAAO,KAAK,gBAAgB,UAAU,SAAS;AAAA;AAAA,IAGtD,cAAc;AAEP,UAAI,KAAK,iBAAiB;AACtB;AAAA;AAGJ,WAAK,oBAAoB,QAAQ;AACvC,WAAK,qBAAqB;AAC1B,WAAK,gBAAgB,UAAU,IAAI;AAG7B,iBAAW,MAAM,KAAK,oBAAoB,YAAY,GAAG;AAAA;AAAA,IAGhE,cAAc;AACP,WAAK,aAAa;AACxB,WAAK,gBAAgB,UAAU,OAAO;AAChC,WAAK,oBAAoB,QAAQ;AACjC,WAAK,oBAAoB;AACzB,UAAI,KAAK,iBAAiB;AACtB,aAAK;AAAA;AAET,UAAI,KAAK,eAAe,MAAM;AAC1B,aAAK;AAAA;AAAA;AAAA,IAIhB,eAAe;AACd,aAAO,KAAK,gBAAgB,UAAU,SAAS;AAAA;AAAA,IAG7C,yBAAyB,GAAG;AACxB,UAAI,EAAE,OAAO,YAAY,KAAK;AAC1B,UAAE;AACF,YAAI,KAAK,iBAAiB;AACtB,eAAK,kBAAkB,EAAE,OAAO,QAAQ;AAAA,eACrC;AACH,eAAK,eAAe,EAAE,OAAO,QAAQ;AAAA;AAEzC,aAAK;AAEL,aAAK,SAAS,KAAK,YAAY;AAAA;AAAA;AAAA,IAI1C,qBAAqB,GAAG;AACvB,UAAI,EAAE,OAAO,OAAO,KAAK,eAAe,IAAI;AAC3C,aAAK;AAAA;AAAA;AAAA,IAIP,qBAAqB;AACd,UAAI,KAAK,iBAAiB;AACtB,aAAK,gCAAgC,iBAAiB,4BAA4B,QAAQ,OAAK,EAAE,UAAU,OAAO;AAClH,aAAK,gBAAgB,UAAU,IAAI;AAAA,aAChC;AACH,aAAK,qBAAqB,iBAAiB,gBAAgB,QAAQ,OAAK,EAAE,UAAU,OAAO;AAC3F,YAAI,KAAK,cAAc;AACnB,eAAK,aAAa,UAAU,IAAI;AAChC,eAAK;AAAA;AAAA;AAAA;AAAA,IAKpB,aAAa;AAEZ,UAAI,KAAK,aAAa,YAAY,KAAK,oBAAoB,WAAW;AACrE,aAAK,oBAAoB,YAAY,KAAK,aAAa;AAAA;AAGxD,UAAI,KAAK,aAAa,YAAY,KAAK,aAAa,eAAe,KAAK,oBAAoB,eAAe,KAAK,oBAAoB,WAAW;AAC9I,aAAK,oBAAoB,YAAY,KAAK,aAAa,YAAY,KAAK,aAAa,eAAe,KAAK,oBAAoB;AAAA;AAAA;AAAA,IAI5H,eAAe,SAAS;AAEpB,UAAI,AAAS,QAAQ,YAAjB,MAA0B;AAC1B,aAAK,aAAa;AAClB,YAAI,KAAK,iBAAiB;AACtB,eAAK,kBAAkB;AAAA,eACpB;AACH,eAAK,eAAe;AAAA;AAExB,aAAK;AAAA;AAAA;AAAA,IAIhB,WAAW;AACJ,UAAI,KAAK,iBAAiB;AACtB,cAAM,WAAW,KAAK,gBAAgB;AACtC,aAAK,aAAa;AAClB,YAAI,UAAU;AACV,eAAK,kBAAkB;AACvB,eAAK;AAAA;AAAA,aAEN;AACH,cAAM,WAAW,KAAK,aAAa;AACnC,aAAK,aAAa;AAClB,YAAI,UAAU;AACV,eAAK,eAAe;AACpB,eAAK;AAAA;AAAA;AAAA;AAAA,IAKpB,SAAS;AACF,UAAI,KAAK,iBAAiB;AACtB,cAAM,WAAW,KAAK,gBAAgB;AACtC,aAAK,aAAa;AAClB,YAAI,UAAU;AACV,eAAK,kBAAkB;AACvB,eAAK;AAAA;AAAA,aAEN;AACH,cAAM,WAAW,KAAK,aAAa;AACnC,aAAK,aAAa;AAClB,YAAI,UAAU;AACV,eAAK,eAAe;AACpB,eAAK;AAAA;AAAA;AAAA;AAAA,IAKjB,gBAAgB;AACZ,aAAO,AAAS,KAAK,kBAAd;AAAA;AAAA,IAGX,YAAY,gBAAgB;AACxB,WAAK,+BAA+B,gBAAgB;AAEpD,YAAM,gBAAgB,KAAK,+BAA+B;AAC1D,WAAK,6BAA6B,MAAM,YAAY,gBAAgB;AACpE,WAAK,+BAA+B,UAAU,IAAI;AAElD,WAAK,kBAAkB,eAAe,cAAc;AACpD,WAAK,gBAAgB;AACrB,WAAK;AAEL,WAAK,oBAAoB,WAAW;AAEpC,WAAK,oBAAoB;AAAA;AAAA,IAG7B,aAAa,iBAAiB,MAAM;AAChC,UAAI,AAAS,mBAAT,MAAyB;AACzB,yBAAiB,SAAS,cAAc;AAAA;AAE5C,WAAK,+BAA+B,UAAU,OAAO;AACrD,WAAK,gBAAgB,UAAU,OAAO;AACtC,WAAK,6BAA6B,MAAM,YAAY;AACpD,WAAK,kBAAkB;AACvB,WAAK,gBAAgB;AACrB,WAAK,oBAAoB,WAAW;AACpC,WAAK,oBAAoB;AAAA;AAAA,IAGhC,SAAS,cAAc,OAAO;AACvB,UAAI,KAAK,iBAAiB;AACtB,aAAK,UAAU,KAAK,iBAAiB;AACrC;AAAA;AAEJ,UAAI,KAAK,aAAa,UAAU,SAAS,sBAAsB;AAC3D,cAAM,UAAU,KAAK,aAAa,cAAc;AAChD,aAAK,YAAY;AACjB;AAAA;AAGJ,WAAK,UAAU,KAAK,cAAc;AAAA;AAAA,IAGtC,UAAU,MAAM,aAAa;AACzB,WAAK;AACL,YAAM,OAAO,KAAK,cAAc;AAChC,YAAM,MAAM,KAAK;AAIjB,UAAI,KAAK,aAAa,YAAY,IAAI;AAClC;AAAA;AAGJ,UAAI,AAAgB,KAAK,QAAQ,WAA7B,aAAqC;AACrC,kBAAU,UAAU,UAAU;AAC9B;AAAA;AAGJ,UAAI,aAAa;AACb,eAAO,KAAK,KAAK;AAAA,aACd;AACH,eAAO,WAAW;AAAA;AAAA;AAAA,IAI7B,wBAAwB;AACvB,aAAO,MAAM,KAAK,KAAK,oBAAoB,YAAY,SAAS,KAAK;AAAA;AAAA,UAGhE,yBAAyB;AAC9B,YAAM,KAAK;AACX,WAAK;AAAA;AAAA,UAGA,gBAAgB;AAIf,UAAI,CAAE,KAAK,YAAY;AACnB,aAAK;AAEL,YAAI,KAAK,oBAAoB,UAAU,IAAI;AAEvC,eAAK,cAAc,IAAI,0BAAK,KAAK,cAAc,KAAK;AACpD,eAAK,eAAe,KAAK,YAAY,OAAO,KAAK,oBAAoB,OAAO,IAAI,OAAK,EAAE;AAAA;AAE3F;AAAA;AAGJ,UAAI,KAAK,oBAAoB,MAAM,WAAW,GAAG;AAC7C,aAAK,oBAAoB,UAAU,IAAI;AACvC,YAAI,UAAU;AACd,YAAI,KAAK,WAAW,yBAAyB,MAAM;AAC/C,oBAAU,MAAM,KAAK,WAAW;AAAA;AAEpC,aAAK,gBAAgB;AAErB,aAAK,oBAAoB,UAAU,OAAO;AAAA,aACvC;AAEH,aAAK,oBAAoB,UAAU,IAAI;AACvC,cAAM,UAAU,MAAM,KAAK,WAAW,eAAe,KAAK,oBAAoB;AAC9E,aAAK,gBAAgB;AAErB,aAAK,oBAAoB,UAAU,OAAO;AAAA;AAAA;AAAA,IAoBrD,qBAAqB;AACpB,YAAM,WAAW,SAAS,cAAc;AACxC,eAAS,KAAK;AAEd,WAAK,aAAa,QAAQ,OAAK;AAC9B,iBAAS,YAAY;AAAA;AAGtB,WAAK,oBAAoB,gBAAgB,GAAG,SAAS;AAErD,UAAI,CAAC,KAAK,cAAc,CAAC,KAAK,yBAAyB;AACtD,aAAK,eAAe,KAAK,aAAa;AAAA;AAGvC,WAAK;AAAA;AAAA;AAtzBP,MAAO,oCAAP;;;AOhBA,6BAAoC;AAAA,IAehC,aAAa;AAAA,IAOb,iBAAiB;AAAA,IAOjB,qBAAqB;AAAA,IAQpB,oBAAoB;AAAA,IAQpB,kBAAkB;AAAA,IAOlB,UAAU;AAAA;AApDf,MAAO,gCAAP;;;ACDA,+BAAsC;AAAA,IAElC,OAAO;AAAA,IAGP,cAAc;AAAA,IAGd,YAAY;AAAA,IAEZ,YAAY,YAAY;AACpB,WAAK,OAAO;AACZ,WAAK;AAAA;AAAA,IAMT,iBAAiB;AACb,cAAQ,IAAI,+CAA+C,KAAK;AAChE,iBAAW,WAAW,eAAe;AAAA;AAAA,IAOzC,iBAAiB;AACb,aAAO;AAAA;AAAA,IAOX,WAAW;AACP,WAAK,YAAY;AACjB,WAAK;AAAA;AAAA,IAOT,sBAAsB;AAClB,WAAK,YAAY,QAAQ,WAAW,WAAW;AAAA;AAAA,IAQnD,+BAA+B;AAC3B,aAAO;AAAA;AAAA,IAMX,YAAY,KAAK,OAAO;AAAA;AAAA;AA5D5B,MAAO,mCAAP;;;ACPA,kCAAyC;AAAA,IAMrC,YAAY,qBAAqB;AAG7B,UAAI,CAAE,SAAS,cAAc,kBAAkB;AAC3C;AAAA;AAMJ,WAAK,kBAAkB;AAAA,QACnB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAMJ,WAAK,iBAAiB;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAGJ,UAAI,qBAAqB;AACrB,aAAK,sBAAsB,oBAAoB,SAAS,IAAI,sBAAsB;AAAA,aAC/E;AACH,aAAK,sBAAsB;AAAA;AAG/B,YAAM,UAAU,SAAS,eAAe;AAExC,UAAI,CAAC,SAAS;AACV;AAAA;AAGJ,UAAI,uBAAuB,oBAAoB,SAAS,GAAG;AACvD,4BAAoB,QAAQ,QAAM;AAC9B,cAAI,AAAa,OAAO,OAApB,YAA2B,GAAG,SAAS,GAAG;AAC1C,iBAAK,gBAAgB,KAAK,MAAM;AAAA;AAAA;AAAA;AAKpD,cAAQ,IAAI,oBAAoB,KAAK;AAC7B,YAAM,UAAU,SAAS,iBAAiB,KAAK,gBAAgB,KAAK;AAC5E,cAAQ,IAAI,WAAW;AAGf,cAAQ,QAAQ,YAAU;AACtB,aAAK,mBAAmB;AAExB,YAAI,KAAK,WAAW,SAAS;AACzB,gBAAM,iBAAiB,SAAS,cAAc;AAC9C,yBAAe,UAAU,IAAI;AAC7B,yBAAe,YAAY;AAE3B,gBAAM,eAAe,SAAS,cAAc;AAC5C,uBAAa,UAAU,IAAI;AAC3B,uBAAa,YAAY;AAEzB,iBAAO,UAAU,IAAI;AAErB,iBAAO,YAAY;AACnB,iBAAO,YAAY;AAEnB,yBAAe,iBAAiB,SAAS,KAAK,eAAe,KAAK,OAAO,OAAO;AAChF,uBAAa,iBAAiB,SAAS,KAAK,aAAa,KAAK,OAAO,OAAO;AAAA;AAAA;AAIpF,YAAM,gBAAgB,MAAM,KAAK,SAAS,OAAO,YAAU;AACvD,YAAI,KAAK,oBAAoB,SAAS,OAAO,KAAK;AAC9C,iBAAO;AAAA;AAGX,YAAI,KAAK,WAAW,SAAS;AACzB,iBAAO;AAAA;AAIX,YACI,OAAO,iBAAiB,KACxB,OAAO,gBAAgB,GACzB;AACE,iBAAO;AAAA;AAGX,eAAO;AAAA;AAGX,cAAQ,IAAI,mBAAmB;AAM/B,YAAM,qBAAqB,SAAS,cAAc;AAClD,yBAAmB,KAAK;AACxB,yBAAmB,UAAU,IAAI,iBAAiB;AAClD,yBAAmB,MAAM,SAAO;AAChC,yBAAmB,MAAM,QAAM;AAC/B,UAAI,cAAc,WAAW,GAAG;AAC5B,2BAAmB,MAAM,UAAQ;AAAA;AAOrC,YAAM,gBAAgB,SAAS,cAAc;AAC7C,oBAAc,OAAK;AACnB,oBAAc,KAAG;AACjB,oBAAc,UAAU,IAAI,UAAU;AACtC,oBAAc,YAAU,wCAAwC,cAAc,SAAS;AACvF,oBAAc,aAAa,iBAAiB;AAK5C,oBAAc,iBAAiB,SAAS,KAAK,mBAAmB,KAAK,OAAO;AAK5E,yBAAmB,YAAY;AAK/B,YAAM,kBAAkB,SAAS,eAAe;AAChD,sBAAgB,YAAY;AAK5B,YAAM,eAAe,SAAS,cAAc;AAE5C,mBAAa,KAAG;AAChB,mBAAa,MAAM,UAAQ;AAC3B,mBAAa,QAAQ,OAAK;AAE1B,YAAM,oBAAoB,SAAS,cAAc;AACjD,wBAAkB,KAAK;AAEvB,oBAAc,QAAQ,YAAU;AAE5B,0BAAkB,OAAO;AAAA;AAM7B,mBAAa,YAAY;AACzB,YAAM,aAAa,SAAS,eAAe;AAC3C,iBAAW,YAAY;AAAA;AAAA,IAS3B,WAAW,YAAY;AACnB,aAAO,KAAK,eAAe,OAAQ,CAAC,OAAO,YAAY;AACnD,eAAO,SAAS,WAAW,UAAU,SAAS;AAAA,SAC/C;AAAA;AAAA,IAGP,eAAe,IAAI;AACf,YAAM,kBAAkB,SAAS,eAAe;AAChD,YAAM,QAAQ,SAAS,eAAe;AACtC,YAAM,aAAa,SAAS,eAAe;AAC3C,YAAM,YAAY,SAAS,eAAe;AAC1C,YAAM,QAAQ,SAAS,UAAU,WAAW;AAC5C,YAAM,SAAS,GAAG,OAAO,QAAQ,KAAK,gBAAgB,KAAK;AAC3D,YAAM,WAAW,OAAO;AACxB,cAAQ,IAAI,eAAe;AAC3B,iBAAW,YAAY;AACvB,UAAI,UAAU,GAAG;AACb,wBAAgB,MAAM,UAAU;AAAA;AAGpC,WAAK;AAEL,gBAAU,YAAY,SAAS,UAAU,WAAW,MAAM;AAE1D,WAAK,qBAAqB;AAAA;AAAA,IAG9B,qBAAqB,UAAU;AAC3B,WAAK,oBAAoB,KAAK;AAE9B,UAAI,AAAa,OAAO,YAApB,UAA8B;AAC9B,gBAAQ,QAAQ,YAAY;AAAA,UACxB,QAAU;AAAA,UACV;AAAA;AAAA,aAED;AACH,eAAO,aAAa,QAAQ,uBAAuB,KAAK,UAAU,KAAK;AAAA;AAAA;AAAA,IAI/E,aAAa,IAAI;AACb,YAAM,kBAAkB,SAAS,eAAe;AAChD,YAAM,aAAa,SAAS,eAAe;AAC3C,YAAM,YAAY,SAAS,eAAe;AAC1C,YAAM,QAAQ,SAAS,UAAU,WAAW;AAC5C,YAAM,SAAS,GAAG,OAAO,QAAQ,KAAK,gBAAgB,KAAK;AAC3D,YAAM,WAAW,OAAO;AACxB,cAAQ,IAAI,cAAc;AAE1B,aAAO;AAEP,YAAM,UAAU,SAAS,cAAc;AACvC,YAAM,IAAI,SAAS,cAAc;AACjC,cAAQ,UAAU,IAAI,UAAU;AAChC,QAAE,cAAc;AAChB,cAAQ,YAAY;AACpB,iBAAW,YAAY;AAEvB,WAAK;AAQL,gBAAU,YAAa,SAAQ,GAAG;AAClC,WAAK,oBAAoB;AAAA;AAAA,IAG7B,oBAAoB,UAAU;AAC1B,WAAK,oBAAoB,KAAK;AAE9B,UAAI,AAAa,OAAO,YAApB,UAA8B;AAC9B,gBAAQ,QAAQ,YAAY;AAAA,UACxB,QAAU;AAAA,UACV;AAAA;AAAA,aAED;AACH,aAAK,sBAAsB,KAAK,oBAAoB,OAAQ,QAAM,OAAO;AACzE,eAAO,aAAa,QAAQ,uBAAuB,KAAK,UAAU,KAAK;AAAA;AAAA;AAAA,IAO/E,mBAAmB,QAAQ;AACvB,UAAI,OAAO,MAAM,OAAO,OAAO,MAAM,OAAO,OAAM,WAAW;AACzD;AAAA;AAGJ,YAAM,UAAU,OAAO;AACvB,aAAO,KAAK,MAAM,KAAK,OAAO,WAAW,KAAK;AAAA;AAAA,IAUlD,iCAAiC;AAC7B,aAAO,AAAa,OAAO,OAAO,eAA3B,YAA0C,OAAO,WAAW,QAAQ,OAAO,oBAAoB,SAAS;AAAA;AAAA,IAGnH,yBAAyB;AAErB,UAAI,KAAK,kCAAkC;AACvC;AAAA;AAGJ,YAAM,aAAa,SAAS,eAAe;AAC3C,YAAM,eAAe,SAAS,eAAe;AAC7C,YAAM,SAAS,aAAa;AAC5B,iBAAW,MAAM,YAAY,OAAO,SAAS,MAAM;AAAA;AAAA,IAGvD,mBAAmB,IAAI;AAGnB,UAAI,KAAK,kCAAkC;AACvC;AAAA;AAGJ,YAAM,mBAAmB;AACzB,YAAM,aAAa,SAAS,eAAe;AAC3C,YAAM,eAAe,SAAS,eAAe;AAC7C,UAAI,aAAa,QAAQ,SAAS,MAAM;AACpC,aAAK;AAEL,qBAAa,QAAQ,OAAO;AAC5B,mBAAW,MAAM,aAAa,cAAc,iBAAiB,SAAS;AACtE,mBAAW,MAAM,YAAY;AAC7B,mBAAW,MAAM,WAAW;AAC5B,mBAAW,MAAM,UAAU;AAC3B,qBAAa,MAAM,UAAU;AAC7B,cAAM,SAAS,aAAa;AAC5B,mBAAW,MAAM,YAAY,OAAO,SAAS,MAAM;AAAA,aAIhD;AACH,qBAAa,QAAQ,OAAO;AAC5B,cAAM,SAAS,aAAa;AAC5B,mBAAW,MAAM,YAAY;AAC7B,mBAAW,MAAM;AACb,uBAAa,MAAM,UAAU;AAC7B,qBAAW,MAAM,UAAU;AAC3B,qBAAW,MAAM,aAAa;AAC9B,qBAAW,MAAM,WAAW;AAC5B,qBAAW,MAAM,YAAY;AAC7B,eAAK;AAAA,WACN,mBAAmB;AAAA;AAAA;AAAA,IAK9B,4BAA4B;AACxB,YAAM,YAAY,SAAS,iBAAiB;AAC5C,gBAAU,QAAS,CAAC,QAAQ;AACxB,YAAI,IAAI,MAAM,eAAe,UAAU;AACnC,cAAI,MAAM,aAAa;AAAA,eACpB;AACH,cAAI,MAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAzVvC,MAAO,uCAAP;;;ACAA,iCAAwC;AAAA,IAEpC,cAAc;AAIV,YAAM,KAAK;AAKX,WAAK,aAAa;AAKlB,WAAK,kBAAkB;AAKvB,WAAK,YAAY,SAAS,cAAc;AAExC,UAAI,CAAE,KAAK,WAAW;AAClB;AAAA;AAMJ,WAAK,YAAY,KAAK,UAAU,iBAAiB;AAEjD,eAAS,iBAAiB,SAAS,OAAK,KAAK,YAAY;AAAA;AAAA,IAO7D,YAAY,IAAI;AACZ,UAAI,SAAS,cAAc,YAAY,QAAQ;AAC3C;AAAA;AAGJ,UAAI,GAAG,QAAQ,KAAK;AAChB,aAAK;AAAA,iBACE,GAAG,QAAQ,KAAK;AACvB,aAAK;AAAA,iBACE,GAAG,IAAI,kBAAkB,WAAW,KAAK,eAAe,MAAM;AACrE,aAAK;AAAA;AAAA;AAAA,IAKb,gBAAgB;AACZ,WAAK;AAGL,UAAI,KAAK,eAAe,MAAM;AAC1B,aAAK,kBAAkB;AAAA,aACpB;AACH,aAAK;AAAA;AAET,WAAK;AAAA;AAAA,IAGT,cAAc;AACV,WAAK;AAEL,UAAI,KAAK,kBAAkB,GAAG;AAC1B,aAAK;AACL,aAAK;AAAA;AAAA;AAAA,IAIb,iBAAiB;AACb,UAAI,KAAK,eAAe,MAAM;AAC1B,aAAK,UAAU,KAAK,iBAAiB,UAAU,OAAO;AAAA;AAAA;AAAA,IAI9D,cAAc;AACV,WAAK,aAAa,KAAK,UAAU,KAAK;AAEtC,UAAI,CAAE,KAAK,UAAU,KAAK,iBAAiB,UAAU,SAAS,wBAAwB;AAClF,aAAK,UAAU,KAAK,iBAAiB,UAAU,IAAI;AAAA;AAAA;AAAA,IAI3D,mBAAmB;AACf,cAAQ,IAAI;AAEZ,YAAM,OAAO,KAAK,WAAW,cAAc;AAC3C,UAAI,MAAM;AACN,aAAK;AAAA;AAAA;AAAA;AA9FjB,MAAO,qCAAP;;;ACEA,0CAAiD,iCAAiB;AAAA,IAC9D,cAAc;AACV,YAAM;AAAA;AAAA,IAQV,iBAAiB;AACb,UAAI,AAAS,WAAW,WAAW,QAAQ,iBAAvC,MAAqD;AACrD,eAAO;AAAA;AAGX,UAAI,CAAE,SAAS,eAAe,eAAe;AACzC,eAAO;AAAA;AAEX,aAAO;AAAA;AAAA,IAMX,WAAW;AACP,YAAM;AAEN,WAAK,eAAe;AAAA,QAChB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAGJ,WAAK,iBAAiB,WAAW,WAAW,QAAQ;AAEpD,WAAK,OAAO,SAAS,eAAe;AACpC,WAAK,cAAc,SAAS,iBAAkB;AAE9C,YAAM,KAAK,KAAK,aAAa,QAAS,aAAW;AAC7C,YAAI,KAAK,aAAa,SAAS,QAAQ,KAAK;AACxC;AAAA;AAEJ,gBAAQ,UAAU,IAAI;AAAA;AAG1B,UAAI,KAAK,mBAAmB,UAAU;AAClC,aAAK,KAAK,UAAU,OAAO;AAAA;AAI/B,WAAK,SAAS,SAAS,cAAc;AACrC,WAAK,OAAO,KAAK;AACjB,WAAK,OAAO,YAAY;AAExB,WAAK,OAAO,iBAAiB,SAAS,OAAK;AACvC,aAAK,KAAK,UAAU,OAAO;AAE3B,aAAK,iBAAiB,KAAK,mBAAmB,SAAS,WAAW;AAElE,gBAAQ,QAAQ,YAAY;AAAA,UACxB,QAAU;AAAA,UACV,gBAAkB,KAAK;AAAA;AAAA;AAI/B,WAAK,KAAK,sBAAsB,YAAY,KAAK;AAAA;AAAA;AAlEzD,MAAO,sCAAP;;;ACGA,8CAAqD,iCAAiB;AAAA,IAClE,cAAc;AACV,YAAM;AAGN,YAAM,eAAe,OAAO,KAAK,WAAW,WAAW;AACvD,eAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC1C,cAAM,kBAAkB,aAAa;AACrC,cAAM,eAAe,WAAW,WAAW,UAAU;AAErD,aAAK,YAAY,KAAM,KAAK,uBAAuB;AAAA;AAIvD,WAAK,YAAY,KAAM,IAAI,0BAAW,MAAM,WAAW,KAAK,SAAS,KAAK;AAG1E,WAAK,YAAY,KAAM,IAAI,0BAAW,UAAU,kBAAkB,KAAK,cAAc,KAAK;AAC1F,WAAK,YAAY,KAAM,IAAI,0BAAW,QAAQ,kBAAkB,KAAK,cAAc,KAAK;AAAA;AAAA,IAQ5F,iBAAiB;AAEb,aAAO;AAAA;AAAA,IAMX,WAAW;AACP,YAAM;AAAA;AAAA,IAQV,uBAAuB,UAAU;AAE7B,aAAO,IAAI,0BAAW,SAAS,MAAM,SAAS,MAAM,CAAC,iBAAiB,KAAK,cAAc,cAAc,SAAS;AAAA;AAAA,UAQ9G,cAAc,cAAc,WAAW,OAAO;AAIhD,YAAM,UAAU,MAAM,WAAW,WAAW,SAAS,cAAc;AAEnE,UAAI,CAAE,MAAM,QAAQ,UAAU;AAC1B,eAAO;AAAA;AAGX,aAAO,QAAQ,IAAI,YAAU;AACT,cAAM,OAAO,IAAI;AACjB,aAAK,QAAQ,OAAO;AACpB,aAAK,UAAU,OAAO;AACtB,aAAK,MAAM,OAAO;AAElB,aAAK,eAAe,KAAK,aAAa,OAAO,KAAK,iBAAiB,OAAO,IAAI;AAE9E,eAAO;AAAA;AAAA;AAAA,UAQzB,SAAS,QAAQ;AACnB,UAAI,CAAE,OAAO,OAAO,MAAM,UAAU;AAChC,eAAO;AAAA;AAEX,YAAM,aAAa,MAAM,WAAW,WAAW,cAAc;AAE7D,YAAM,sBAAsB,IAAI;AAEhC,UAAI,CAAE,YAAY;AACd,4BAAoB,QAAQ;AAC5B,eAAO,CAAE;AAAA;AAGb,0BAAoB,QAAQ,YAAY;AACxC,0BAAoB,MAAM,WAAW,KAAK,OAAO,OAAO;AAExD,0BAAoB,eAAe,oBAAoB,aAAa,OAAO,KAAK,iBAAiB,QAAQ;AAEzG,aAAO,CAAE;AAAA;AAAA,IAUb,iBAAiB,QAAQ,aAAa;AAClC,YAAM,gBAAgB;AACtB,oBAAc,KACV,IAAI,2BACA,QACA,YAAY;AAKpB,UAAI,WAAW,WAAW,kBAAkB,aAAa;AAErD,cAAM,WAAW,WAAW,KAAK,UAAU,kBAAkB;AAC7D,sBAAc,KACV,IAAI,2BACA,QACA;AAKR,YAAI,WAAW,WAAW,mBAAmB,kBAAkB;AAC3D,gBAAM,aAAa,WAAW,KAAK,OAAO,YAAY;AACtD,wBAAc,KACV,IAAI,2BACA,oBACA;AAAA;AAAA;AAMhB,YAAM,eAAe,IAAI,2BAAa,aAAa,YAAY;AAC/D,mBAAa,aAAa,eAAe;AACzC,oBAAc,KAAK;AAEnB,aAAO;AAAA;AAAA;AA/If,MAAO,2CAAP;;;ACAA,6CAAoD,iCAAiB;AAAA,IACjE,cAAc;AACV,YAAM;AAEN,WAAK,YAAY,KAAM,IAAI,0BAAW,UAAU,WAAW,KAAK,cAAc,KAAK,mBAAmB,KAAK;AAAA;AAAA,IAQ/G,iBAAiB;AAEb,aAAO;AAAA;AAAA,IAMX,WAAW;AACP,YAAM;AAAA;AAAA,UAQJ,qBAAqB;AACvB,aAAO,MAAM,KAAK,aAAa;AAAA;AAAA,UAO7B,aAAa,cAAc;AAI7B,YAAM,UAAU,MAAM,WAAW,WAAW,WAAW;AAEvD,UAAI,CAAE,MAAM,QAAQ,UAAU;AAC1B,eAAO;AAAA;AAGX,aAAO,QAAQ,IAAI,YAAU;AAET,cAAM,OAAO,IAAI;AACjB,aAAK,QAAQ,OAAO;AACpB,aAAK,UAAU;AAIf,cAAM,oBAAoB,IAAI;AAC9B,0BAAkB,IAAI,iBAAiB;AACvC,0BAAkB,IAAI,KAAK,OAAO;AAClC,aAAK,aAAa,KACd,IAAI,2BACA,QACA,WAAW,KAAK,UAAU,kBAAkB,kBAAkB;AAKtE,eAAO;AAAA;AAAA;AAAA;AAlEnC,MAAO,oCAAP;;;ACDA,2CAAkD,iCAAiB;AAAA,IAC/D,cAAc;AACV,YAAM;AAEN,WAAK,YAAY,KAAM,IAAI,0BAAW,QAAQ,SAAS,KAAK,YAAY,KAAK,iBAAiB,KAAK;AAAA;AAAA,IAQvG,iBAAiB;AAEb,aAAO;AAAA;AAAA,IAMX,WAAW;AACP,YAAM;AAAA;AAAA,UAQH,mBAAmB;AACtB,aAAO,MAAM,KAAK,WAAW;AAAA;AAAA,UAO3B,WAAW,cAAc;AAI3B,YAAM,UAAU,MAAM,WAAW,WAAW,SAAS;AAErD,UAAI,CAAE,MAAM,QAAQ,UAAU;AAC1B,eAAO;AAAA;AAGX,aAAO,QAAQ,IAAI,YAAU;AACT,cAAM,OAAO,IAAI;AACjB,YAAI,OAAO,cAAc,OAAO,WAAW;AACvC,eAAK,QAAQ,GAAG,OAAO,cAAc,OAAO;AAAA;AAEhD,aAAK,SAAS,OAAO;AACrB,aAAK,UAAU,OAAO,MAAM;AAC5B,aAAK,MAAM,WAAW,KAAK,UAAU,0BAA0B,OAAO;AACtE,eAAO;AAAA;AAAA;AAAA;AAvDnC,MAAO,kCAAP;;;ACCA,wCAA+C,iCAAiB;AAAA,IAC5D,cAAc;AACV,YAAM;AAEN,WAAK,YAAY,KAAM,IAAI,0BAAW,QAAQ,SAAS,KAAK,WAAW,KAAK,OAAO,KAAK,iBAAiB,KAAK;AAAA;AAAA,IAQlH,iBAAiB;AACb,aAAO,QAAQ,SAAS,cAAc;AAAA;AAAA,IAM1C,WAAW;AACP,YAAM;AAAA;AAAA,UAQH,mBAAmB;AACtB,aAAO,MAAM,KAAK,WAAW;AAAA;AAAA,UAO3B,WAAW,cAAc;AAQ3B,YAAM,QAAQ,SAAS,iBAAiB;AAExC,UAAI,MAAM,WAAW,GAAG;AACpB,eAAO;AAAA;AAGX,YAAM,aAAa,MAAM,KAAK;AAC9B,YAAM,aAAa,WAAW,IAAI,UAAQ,KAAK,cAAc;AAC7D,YAAM,gBAAgB,WAAW,OAAO,UAAQ,KAAK,UAAU,cAAc,SAAS,aAAa;AAEnG,aAAO,cAAc,IAAI,UAAQ;AAC7B,cAAM,OAAO,IAAI;AACjB,aAAK,QAAQ,KAAK;AAClB,aAAK,UAAU;AACf,aAAK,MAAM,KAAK;AAEhB,aAAK,eAAe,KAAK,aAAa,OAAO,KAAK,iBAAiB;AAEnE,eAAO;AAAA;AAAA;AAAA,IAIf,iBAAiB,aAAa;AAC1B,YAAM,eAAe;AAErB,YAAM,UAAU,YAAY,mBAAmB,cAAc;AAC7D,UAAI,CAAE,SAAS;AACX,eAAO;AAAA;AAGX,YAAM,eAAe,QAAQ,iBAAiB;AAC9C,UAAI,aAAa,WAAW,GAAG;AAC3B,eAAO;AAAA;AAGX,YAAM,oBAAoB,MAAM,KAAK;AACrC,wBAAkB,QAAQ,UAAQ;AAC9B,cAAM,cAAc,IAAI,2BAAY,KAAK,WAAW,KAAK;AACzD,qBAAa,KAAK;AAAA;AAGtB,aAAO;AAAA;AAAA;AArFf,MAAO,qCAAP;;;ACCA,8CAAqD,iCAAiB;AAAA,IAClE,cAAc;AACV,YAAM;AAAA;AAAA,IAQV,iBAAiB;AAGb,UAAI,iBAAiB,SAAS,eAAe;AAE7C,UAAI,CAAE,gBAAgB;AAClB,yBAAiB,SAAS,eAAe;AAAA;AAG7C,UAAI,CAAE,gBAAgB;AAClB,yBAAiB,OAAO,OAAO,aAAa,QAAQ;AAAA;AAGxD,YAAM,mBAAmB,QAAQ;AAGjC,aAAO,aAAa,QAAQ,yBAAyB,mBAAmB,MAAM;AAE9E,aAAO;AAAA;AAAA,IAMX,WAAW;AACP,YAAM;AAAA;AAAA,IAQT,+BAA+B;AAC5B,YAAM,iBAAiB,IAAI;AAC3B,qBAAe,aAAa;AAC5B,qBAAe,iBAAiB;AAChC,qBAAe,oBAAoB,MAAM;AACzC,qBAAe,kBAAkB,CAAC,YAAY,QAAQ;AACtD,qBAAe,UAAU;AAKzB,YAAM,qBAAqB,IAAI;AAC/B,yBAAmB,aAAa;AAChC,yBAAmB,iBAAiB;AACpC,yBAAmB,oBAAoB,CAAC,YAAY,iBAAiB,QAAQ;AAC7E,yBAAmB,kBAAkB,CAAC,YAAY;AAC9C,YAAI,QAAQ,MAAM;AACd,iBAAO,QAAQ;AAAA,eACZ;AACH,cAAI,MAAM,IAAI,IAAI,OAAO,SAAS;AAClC,iBAAO,IAAI,SAAS,IAAI;AAAA;AAAA;AAGhC,yBAAmB,UAAU;AAE7B,aAAO;AAAA,QACH;AAAA,QACA;AAAA;AAAA;AAAA;AAtEZ,MAAO,4CAAP;;;ACyDA,yBAAgC;AAAA,IAM5B,YAAY,SAAS;AAGjB,WAAK,SAAS;AAEd,UAAI,SAAS,eAAe,iCAAiC;AACzD,gBAAQ,IAAI;AACZ,aAAK,SAAS;AACd,eAAO,WAAW;AAAA;AAGtB,WAAK,UAAU;AACf,WAAK,UAAU;AAGf,WAAK,cAAc;AAGnB,WAAK,mBAAmB;AAAA;AAAA,UAOtB,OAAO;AACT,UAAI,CAAE,KAAK,QAAQ;AACf;AAAA;AAIJ,UAAI;AACJ,UAAI;AACJ,UAAI;AACJ,UAAI;AAGJ,UAAI;AACJ,UAAI;AAGJ,WAAK,KAAK,WAAW;AAErB,WAAK,OAAO;AAGZ,UAAI,CAAE,KAAK,GAAG,WAAW;AAKrB,YAAI,CAAE,KAAK,GAAG,aAAa;AAGvB,cAAI,SAAS,KAAK,UAAU,SAAS,cAAc;AAE/C,kBAAM,YAAY,OAAO,aAAa,QAAQ;AAG9C,gBAAI,AAAS,cAAT,MAAoB;AACpB,mBAAK,mBAAmB;AAAA,mBACrB;AACH,mBAAK,OAAO,KAAK,MAAM;AAEvB,kBAAI,CAAE,KAAK,KAAK,KAAK,UAAQ,KAAK,OAAO,SAAS,gBAAgB;AAC9D,qBAAK,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA,aAMrC;AAEH,aAAK,OAAO,KAAK;AAAA;AAIrB,WAAK;AAEL,WAAK,OAAO,KAAK,KAAK,OAAO,KAAK,QAAQ,iBAAiB;AAmB3D,WAAK,KAAK,KAAK,CAAC,GAAG,MAAO,GAAE,cAAc,EAAE,OAAO,cAAc,EAAE,cAAc,EAAE;AAGnF,YAAM,cAAc,KAAK,KAAK,OAAO,UAAS,CAAE,KAAK;AACrD,aAAO,aAAa,QAAQ,mBAAmB,KAAK,UAAU;AAG9D,WAAK;AAEL,WAAK,oBAAoB,IAAI,kCAAkB,KAAK,MAAM,KAAK;AAAA;AAAA,IAMnE,kBAAkB;AAEd,aAAO,KAAK,KAAK,SAAS,QAAS,YAAU;AACzC,YAAI,KAAK,QAAQ,QAAQ,kBAAkB;AACvC,eAAK,QAAQ,QAAQ;AAAA;AAAA;AAa7B,UAAI,AAAS,KAAK,QAAQ,qCAAtB,MAAwD;AACxD,aAAK,+BAA+B,IAAI;AAAA;AAI5C,UAAI,WAAW,WAAW,gBAAgB;AAAA;AAAA;AAAA,IAW9C,mBAAmB,MAAM;AACrB,aAAO,OAAO,KAAK,KAAK,SAAS,SAAS,SACtC,KAAK,QAAQ,MAAM;AAAA;AAAA,IAQ3B,UAAU;AACN,YAAM,QAAQ;AACd,YAAM,UAAU,SAAS,eAAe;AACxC,UAAI,SAAS;AACT,cAAM,cAAc,QAAQ,iBAAiB;AAC7C,oBAAY,QAAQ,QAAM;AACtB,gBAAM,IAAI,GAAG,cAAc;AAC3B,gBAAM,QAAQ,EAAE,cAAc,iBAAiB;AAC/C,gBAAM,SAAS,EAAE;AACjB,gBAAM,cAAc;AACpB,gBAAM,OAAO,IAAI,oCAAmB,OAAO,QAAQ;AACnD,gBAAM,KAAK;AAEX,gBAAM,UAAU,GAAG,cAAc;AACjC,cAAI,CAAC,SAAS;AACV;AAAA;AAEJ,gBAAM,WAAW,QAAQ,iBAAiB;AAC1C,cAAI,CAAC,UAAU;AACX;AAAA;AAEJ,mBAAS,QAAQ,WAAS;AACtB,kBAAM,eAAc;AACpB,kBAAM,aAAa,MAAM;AACzB,kBAAM,cAAc,MAAM;AAC1B,kBAAM,QAAO,IAAI,oCAAmB,YAAY,aAAa;AAC7D,kBAAM,KAAK;AAAA;AAAA;AAAA;AAIvB,aAAO;AAAA;AAAA,IAOX,yBAAyB;AAwBrB,UAAI,aAAa,KAAK,QAAQ,cAAc;AAG5C,YAAM,aAAa,OAAO,KAAK,KAAK;AAEpC,eAAS,IAAE,GAAG,IAAI,WAAW,QAAQ,KAAK;AACtC,qBAAa,WAAW,OAAO,KAAK,QAAQ,WAAW,IAAI;AAAA;AAI/D,mBAAa,WAAW,OACpB;AAAA,QACI;AAAA,UACI,YAAc;AAAA,UACd,gBAAkB;AAAA,UAClB,mBAAqB,MAAM;AAAA,UAC3B,iBAAmB,CAAC,YAAY,QAAQ;AAAA;AAAA,QAE5C;AAAA,UACI,YAAc;AAAA,UACd,gBAAkB;AAAA,UAClB,mBAAqB,CAAC,YAAY,QAAQ;AAAA,UAC1C,iBAAmB,CAAC,YAAY,QAAQ;AAAA;AAAA,QAE5C;AAAA,UACI,YAAc;AAAA,UACd,gBAAkB;AAAA,UAClB,mBAAqB,MAAM;AAAA,UAC3B,iBAAmB,MAAM,SAAS,eAAe,wBAAwB,cAAc,MAAM;AAAA;AAAA,QAEjG;AAAA,UACI,YAAc;AAAA,UACd,gBAAkB;AAAA,UAClB,mBAAqB,CAAC,SAAS,KAAK;AAAA,UACpC,iBAAmB,CAAC,SAAS,KAAK;AAAA,UAClC,SAAW;AAAA;AAAA,QAEf;AAAA,UACI,YAAc;AAAA,UACd,gBAAkB;AAAA,UAClB,mBAAqB,CAAC,SAAS,KAAK;AAAA,UACpC,iBAAmB,CAAC,SAAS,KAAK;AAAA,UAClC,SAAW;AAAA;AAAA,QAEf;AAAA,UACI,YAAc;AAAA,UACd,gBAAkB;AAAA,UAClB,mBAAqB,CAAC,SAAS,SAAS,KAAK;AAAA,UAC7C,iBAAmB,CAAC,SAAS,KAAK;AAAA;AAAA,QAEtC;AAAA,UACI,YAAc;AAAA,UACd,gBAAkB;AAAA,UAClB,mBAAqB,CAAC,SAAS,KAAK;AAAA,UACpC,iBAAmB,CAAC,SAAS,KAAK;AAAA;AAAA,QAEtC;AAAA,UACI,YAAc;AAAA,UACd,oBAAsB;AAAA,UACtB,mBAAqB,MAAM;AAAA,UAC3B,iBAAmB,MAAM;AACrB,gBAAI,WAAW,KAAK,MAAM;AACtB,qBAAO,WAAW,KAAK;AAAA;AAG3B,mBAAO;AAAA;AAAA;AAAA,QAIf;AAAA,UACI,YAAc;AAAA,UACd,gBAAkB;AAAA,UAClB,mBAAqB,MAAM;AAAA,UAC3B,iBAAmB,CAAC,YAAY,QAAQ;AAAA;AAAA,QAG5C;AAAA,UACI,YAAc;AAAA,UACd,gBAAkB;AAAA,UAClB,mBAAqB,MAAM;AAAA,UAC3B,iBAAmB,CAAC,YAAY,QAAQ;AAAA;AAAA,QAE5C;AAAA,UACI,YAAc;AAAA,UACd,gBAAkB;AAAA,UAClB,mBAAqB,CAAC,YAAY,oBAAoB,QAAQ;AAAA,UAC9D,iBAAmB,CAAC,YAAY,QAAQ;AAAA;AAAA;AAKpD,iBAAW,QAAQ,UAAQ;AACvB,YAAI,WAAW;AACf,YAAI,WAAW;AACf,YAAI,KAAK,eAAe,OAAO;AAC3B,qBAAW,QAAQ,OAAO,SAAS,KAAK,SAAS,KAAK;AAAA,mBAC/C,KAAK,eAAe,OAAO;AAClC,cAAI,KAAK,gBAAgB;AACrB,uBAAW,SAAS,iBAAiB,KAAK;AAC1C,uBAAW,QAAQ;AAAA,qBACZ,KAAK,oBAAoB;AAChC,uBAAW,SAAS,iBAAiB,KAAK;AAC1C,uBAAW,SAAS,WAAW;AAE/B,uBAAW,SAAS,iBAAiB;AAAA;AAAA;AAG7C,YAAI,CAAC,UAAU;AACX;AAAA;AAGJ,iBAAS,QAAQ,aAAW;AACxB,gBAAM,UAAU,IAAI,oCAAmB,KAAK,kBAAkB,UAAU,KAAK,gBAAgB,UAAU,IAAI,MAAM;AAEjH,cAAI,KAAK,KAAK,KAAK,cAAY;AAI3B,mBAAO,QAAQ,OAAO;AAAA,cACrB;AACD;AAAA;AAGJ,eAAK,KAAK,KAAK;AAAA;AAAA;AAAA;AAAA,IAQ3B,aAAa;AACT,YAAM,YAAY,SAAS,cAAc;AACzC,gBAAU,KAAK;AAEf,YAAM,UAAU,SAAS,cAAc;AACvC,cAAQ,KAAK;AAEb,YAAM,gBAAgB,SAAS,cAAc;AAC7C,oBAAc,KAAK;AAEnB,YAAM,YAAY,SAAS,cAAc;AACzC,gBAAU,KAAK;AAEf,YAAM,gBAAgB,SAAS,cAAc;AAC7C,oBAAc,KAAK;AAEnB,YAAM,kBAAkB,SAAS,cAAc;AAC/C,sBAAgB,KAAK;AACrB,sBAAgB,YAAY;AAE5B,YAAM,QAAQ,SAAS,cAAc;AACrC,YAAM,KAAK;AACX,YAAM,OAAO;AACb,YAAM,OAAO;AAEb,YAAM,aAAa,gBAAgB;AAEnC,YAAM,gBAAgB,SAAS,cAAc;AAC7C,oBAAc,KAAK;AAEnB,YAAM,gBAAgB,SAAS,cAAc;AAC7C,oBAAc,KAAK;AAEnB,YAAM,OAAO,SAAS,cAAc;AACpC,WAAK,KAAK;AAEV,YAAM,mBAAmB,SAAS,cAAc;AAChD,uBAAiB,KAAK;AAEtB,gBAAU,YAAY;AACtB,cAAQ,YAAY;AACpB,cAAQ,YAAY;AACpB,gBAAU,YAAY;AACtB,gBAAU,YAAY;AACtB,cAAQ,YAAY;AACpB,cAAQ,YAAY;AACpB,oBAAc,YAAY;AAC1B,oBAAc,YAAY;AAC1B,cAAQ,YAAY;AAEpB,UAAI,SAAS,eAAe,iBAAiB,KAAK,QAAQ,wBAAwB,MAAM;AACpF,cAAM,YAAY,SAAS,cAAc;AACzC,kBAAU,YAAY;AACtB,cAAM,WAAW,SAAS,eAAe;AACzC,iBAAS,YAAY;AAGrB,cAAM,iBAAiB,SAAS,OAAK,KAAK,kBAAkB;AAG5D,cAAM,cAAc,SAAS,cAAc;AAC3C,oBAAY,KAAK;AACjB,oBAAY,YAAY,KAAK;AAC7B,oBAAY,iBAAiB,SAAS,OAAK,MAAM;AAEjD,gBAAQ,aAAc,aAAa;AAAA,aAChC;AAEH,iBAAS,cAAc,KAAK,QAAQ,mBAAmB,QAAQ,YAAY;AAAA;AAAA;AAAA,IASnF,eAAe,QAAQ;AACnB,cAAQ,IAAI,wBAAwB,OAAO;AAC3C,WAAK,QAAQ,OAAO,QAAQ;AAAA;AAAA,IAUhC,mBAAmB,YAAY;AAC3B,cAAQ,IAAI,0CAA0C,WAAW;AAEjE,iBAAW,WAAW,YAAY,WAAW,WAAW;AAAA;AAAA,IAQ5D,0BAA2B;AACvB,UAAI,aAAa;AACjB,UAAI,WAAW,KAAK,QAAQ,aAAa;AAEzC,UAAK,SAAS,MAAO;AACjB,sBAAc;AAAA;AAElB,UAAK,SAAS,MAAO;AACjB,sBAAc;AAAA;AAElB,UAAK,SAAS,KAAM;AAChB,sBAAc;AAAA;AAElB,UAAK,SAAS,OAAQ;AAClB,sBAAc;AAAA;AAElB,oBAAc,SAAS;AACvB,aAAO;AAAA;AAAA;AAvdf,MAAO,4BAAP;;;AC/DA,iBAAwB;AAAA,IAEpB,cAAc;AAGV,WAAK,UAAU;AACf,WAAK,OAAO;AACZ,WAAK,WAAW;AAChB,WAAK,aAAa;AAAA;AAAA,UAGhB,eAAe;AAEjB,WAAK,cAAc,OAAO,aAAa,QAAQ;AAG/C,WAAK,UAAU,OAAO,aAAa,QAAQ;AAC3C,WAAK,OAAO,OAAO,aAAa,QAAQ;AAKxC,WAAK,YAAY,KAAK;AAKtB,YAAM,KAAK;AAMX,WAAK,cAAc,KAAK,SAAS,KAAK;AAGtC,aAAO,aAAa,QAAQ,wBAAwB,KAAK;AAAA;AAAA,IAG7D,eAAe;AACX,aAAO,SAAS,KAAK,UAAU,SAAS;AAAA;AAAA,IAS5C,oBAAqB,KAAM;AACvB,UAAI,IAAI,SAAS,MAAM;AACnB,eAAO;AAAA,aACJ;AACH,eAAO,MAAM;AAAA;AAAA;AAAA,UAaf,QAAQ,KAAK,yBAAuB,IAAI;AAG1C,YAAM,OAAO;AAAA,QACT,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,OAAO;AAAA,QACP,aAAa;AAAA;AAGjB,YAAM,WAAW,MAAM,MAAM,KAAK;AAElC,UAAI,SAAS,cAAc,CAAC,SAAS,IAAI,SAAS,yBAAyB;AACvE,eAAO;AAAA;AAGX,UAAK,CAAE,SAAS,IAAK;AACjB,eAAO;AAAA;AAGX,aAAO,SAAS;AAAA;AAAA,UAGd,kBAAkB,MAAM,yBAAuB,IAAI;AACrD,UAAI,aAAa;AACjB,UAAI;AAGJ,eAAS,IAAE,GAAG,IAAE,KAAK,QAAQ,KAAK;AAC9B,YAAI;AAAY;AAChB,iBAAS,MAAM,KAAK,QAAQ,KAAK,IAAI;AACrC,YAAI,WAAW,OAAO;AAClB,uBAAa;AAAA;AAAA;AAGrB,aAAO;AAAA;AAAA,UAOL,qBAAsB,SAAU;AAClC,YAAM,gBAAgB,KAAK,oBAAoB;AAU/C,aAAO,gBAAgB;AAAA;AAAA,UAOrB,YAAY;AACd,YAAM,aAAa,IAAI,IAAI,OAAO;AAClC,YAAM,SAAS,KAAK,oBAAoB,WAAW;AASnD,aAAO;AAAA;AAAA,IAQX,qBAAqB,SAAS;AAE1B,aAAO,QAAQ,QAAQ,eAAe;AAAA;AAAA,UAGpC,UAAU;AAGZ,YAAM,UAAU,SAAS,cAAc;AAEvC,UAAI,SAAS;AACT,aAAK,aAAa,QAAQ;AAAA;AAG9B,UAAI,KAAK,WAAW;AAEhB,aAAK,UAAU,OAAO,SAAS,KAAK,MAAM,iBAAiB;AAC3D,aAAK,OAAO,SAAS,eAAe,0BAA0B,cAAc,KAAK;AAGjF,eAAO,aAAa,QAAQ,2BAA2B,KAAK;AAC5D,eAAO,aAAa,QAAQ,wBAAwB,KAAK;AAAA,iBAClD,CAAE,KAAK,WAAW,CAAE,KAAK,MAAM;AAKtC,YAAI,SAAS,eAAe,eAAe;AACvC,eAAK,UAAU,SAAS,eAAe,0BAA0B,cAAc,KAAK;AAEpF,cAAI,KAAK,YAAY;AACjB,gBAAI,KAAK,WAAW,SAAS,aAAa;AACtC,mBAAK,OAAO,KAAK,WAAW,QAAQ,YAAY;AAAA;AAEpD,gBAAI,KAAK,WAAW,SAAS,yBAAyB;AAClD,mBAAK,OAAO,KAAK,WAAW,QAAQ,2BAA2B;AAAA;AAAA,iBAEhE;AAEH,iBAAK,OAAO,KAAK,qBAAqB,KAAK;AAAA;AAAA,eAG5C;AAGH,cAAI,KAAK,YAAY;AACjB,gBAAI,KAAK,WAAW,SAAS,aAAa;AACtC,mBAAK,OAAO,KAAK,WAAW,QAAQ,YAAY;AAAA;AAEpD,gBAAI,KAAK,WAAW,SAAS,yBAAyB;AAClD,mBAAK,OAAO,KAAK,WAAW,QAAQ,2BAA2B;AAAA;AAGnE,gBAAI,KAAK,MAAM;AACX,mBAAK,UAAU,MAAM,KAAK,qBAAsB,KAAK;AAAA,mBAClD;AACH,mBAAK,UAAU,KAAK;AAAA;AAAA,iBAErB;AAEH,iBAAK,OAAU,MAAM,KAAK;AAC1B,gBAAI,KAAK,MAAM;AACX,mBAAK,UAAU,MAAM,KAAK,qBAAqB,KAAK;AAAA;AAAA;AAAA;AAAA;AAOpE,UAAI,KAAK,SAAS;AACd,aAAK,UAAU,KAAK,QAAQ,QAAQ,WAAW;AAAA;AAEnD,UAAI,KAAK,MAAM;AACX,aAAK,OAAO,KAAK,KAAK,QAAQ,WAAW;AAAA;AAAA;AAAA;AA1NrD,MAAO,mBAAP;;;ACGA,6BAAoC;AAAA,IAEhC,cAAc;AAGV,WAAK,QAAQ;AAAA;AAAA,UAGX,UAAU,cAAc;AAE1B,UAAI,AAAc,KAAK,MAAM,YAAY,kBAArC,QAAoD;AACpD,eAAO,KAAK,MAAM,YAAY;AAAA;AAIlC,YAAM,WAAW,MAAM,KAAK,OACxB,UACA;AAAA,QACI,QAAQ;AAAA,QACR,UAAU;AAAA;AAIlB,UAAI,aAAa,OAAO;AACpB,eAAO;AAAA;AAIX,YAAM,SAAS,MAAM,SAAS;AAG9B,WAAK,MAAM,YAAY,gBAAgB;AAEvC,aAAO;AAAA;AAAA,UAGL,SAAS,SAAS;AAEpB,UAAI,AAAc,KAAK,MAAM,WAAW,aAApC,QAA8C;AAC9C,eAAO,KAAK,MAAM,WAAW;AAAA;AAIjC,YAAM,WAAW,MAAM,KAAK,OACxB,UAAU;AAGd,UAAI,aAAa,OAAO;AACpB,eAAO;AAAA;AAIX,YAAM,SAAS,MAAM,SAAS;AAE9B,UAAI,gBAAgB,CAAE;AAGtB,WAAK,MAAM,WAAW,WAAW;AAEjC,aAAO;AAAA;AAAA,UAGL,aAAa,cAAc;AAE7B,UAAI,AAAc,KAAK,MAAM,eAAe,kBAAxC,QAAuD;AACvD,eAAO,KAAK,MAAM,eAAe;AAAA;AAIrC,YAAM,WAAW,MAAM,KAAK,OACxB,aACA;AAAA,QACI,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,MAAM;AAAA;AAId,UAAI,aAAa,OAAO;AACpB,eAAO;AAAA;AAGX,YAAM,SAAS,MAAM,SAAS;AAG9B,WAAK,MAAM,eAAe,gBAAgB;AAE1C,aAAO;AAAA;AAAA,UAIL,OAAO,MAAM,OAAO,IAAI;AAC1B,YAAM,aAAa,WAAW,WAAW,UAAU;AAEnD,YAAM,OAAO;AAAA,QACT,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,MAAM;AAAA,QACN,OAAO;AAAA,QACP,aAAa;AAAA;AAIjB,UAAI,WAAW,WAAW,UAAU;AAChC,aAAK,WAAW,WAAW,WAAW;AAAA;AAG1C,YAAM,SAAS,WAAW,WAAW,gBAAgB;AAErD,YAAM,WAAW,MAAM,MAAM,GAAG,aAAa,SAAS,UAAU;AAEhE,UAAK,SAAS,WAAW,KAAM;AAC3B,eAAO;AAAA;AAEX,UAAM,SAAS,SAAS,OAAO,SAAS,UAAU,KAAO;AACrD,mBAAW,WAAW,kBAAkB,kBAAkB;AAAA;AAG9D,aAAO;AAAA;AAAA;AAtHf,MAAO,gCAAP;;;ACAA,8BAAqC;AAAA,IAEjC,cAAc;AAGV,WAAK,QAAQ;AAAA;AAAA,UAGX,SAAS,cAAc;AAEzB,UAAI,AAAc,KAAK,MAAM,cAAc,kBAAvC,QAAsD;AACtD,eAAO,KAAK,MAAM,cAAc;AAAA;AAIpC,YAAM,WAAW,MAAM,KAAK,MACxB,SACA;AAIJ,YAAM,SAAS,MAAM,SAAS;AAK9B,YAAM,wBAAwB,aAAa;AAC3C,YAAM,UAAU,OAAO,KAAK;AAC5B,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACrC,cAAM,SAAS,QAAQ;AACvB,YAAI,CAAE,OAAO,QAAQ,MAAM,cAAc,SAAS,wBAAwB;AACtE,iBAAO,OAAO;AAAA;AAAA;AAKtB,WAAK,MAAM,cAAc,gBAAgB;AAEzC,aAAO;AAAA;AAAA,UAGL,MAAM,MAAM,OAAO,IAAI;AACzB,YAAM,YAAY,WAAW,WAAW,UAAU;AAElD,YAAM,OAAO;AAAA,QACT,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,MAAM;AAAA,QACN,OAAO;AAAA,QACP,aAAa;AAAA;AAIjB,UAAI,WAAW,WAAW,UAAU;AAChC,aAAK,WAAW,WAAW,WAAW;AAAA;AAG1C,YAAM,SAAS,WAAW,WAAW,gBAAgB;AAErD,YAAM,WAAW,MAAM,MAAM,GAAG,YAAY,SAAS;AAErD,UAAI,SAAS,SAAS,OAAO,SAAS,UAAU,KAAK;AACjD,mBAAW,WAAW,kBAAkB,kBAAkB;AAAA;AAG9D,aAAO;AAAA;AAAA;AAjEf,MAAO,kCAAP;;;ACIA,MAAM,eAAe;AAOrB,wBAAsB,UAAU;AAE5B,QAAI,OAAO,WAAW,eAAgB,aAAa;AAE/C;AAAA;AAEJ,eAAW,aAAa;AAGxB,QAAI,OAAO,SAAS,kBAAmB,aAAa;AAChD,cAAQ,IAAI;AACZ;AAAA;AAGJ,eAAW,oBAAoB,SAAS;AAExC,YAAQ,IAAI;AAGZ,eAAW,OAAO,IAAI;AAGtB,UAAM,WAAW,KAAK;AAEtB,YAAQ,IAAI;AAGZ,eAAW,aAAa,IAAI;AAC5B,UAAM,WAAW,WAAW;AAC5B,UAAM,WAAW,WAAW;AAC5B,eAAW,iBAAiB,IAAI;AAChC,eAAW,kBAAkB,IAAI;AAEjC,YAAQ,IAAI;AAEZ,eAAW,aAAa,IAAI,0BAAW,WAAW;AAClD,UAAM,WAAW,WAAW;AAK5B,UAAM,WAAW,WAAW;AAE5B,QAAI,SAAS,cAAc,iBAAiB;AACxC,iBAAW,sBAAsB,IAAI,qCAAoB,SAAS,cAAc;AAAA;AAAA;AAOxF,WAAS,iBAAiB,oBAAoB,OAAM,MAAK;AACxD,eAAW,oBAAoB;AAC/B,eAAW,kBAAkB,gBAAgB;AAAA,MAE5C,cAAc,WAAW,aAAa;AAAA,MAEhC,mCAAmC;AAAA,MACnC,oCAAoC;AAAA,MAEpC,mBAAmB;AAAA,MACnB,iCAAiC,WAAW,aAAa,0BAA0B;AAAA,MACnF,gBAAgB,WAAW,aAAa,mBAAmB;AAAA,MAC3D,qBAAuB,KAAK,MAAM,OAAO,aAAa,QAAQ,2BAA2B,IAAI;AAAA,MAC7F,WAAa,WAAW,aAAa,iBAAiB;AAAA,MACtD,oBAAoB,WAAW,aAAa,sBAAsB;AAAA;AAEzE,UAAM,OAAO,WAAW;AAAA;",
    66  "names": []
    77}
  • turbo-admin/trunk/readme.txt

    r2748309 r2835882  
    44Tags: menu, commands, shortcuts
    55Requires at least: 4.9
    6 Tested up to: 6.0
     6Tested up to: 6.1
    77Requires PHP: 7.2
    8 Stable tag: 1.9.0
     8Stable tag: 1.12.0
    99License: GPLv2 or later
    1010License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    3232* (Experimental/Beta): List table keyboard shortcuts - use vim-like keys to navigate lsit tables.
    3333
    34 If you love this plugin, you can get Turbo Admin on ALL your sites without needing to install the plugin, with the browser extension version!
    35 
    36 PLUS the browser extension has features not present in the plugin because, well, they only make sense in the extension!
    37 
     34If you love this plugin, you can get Turbo Admin on ALL your sites without needing to install the plugin, PLUS additional premium features, with [the browser extension version](https://turbo-admin.com/)!
     35
     36PLUS the browser extension has features not present in the plugin. Some features only make sense in the extension, others are considered "premium" and are only available in the browser extension.
     37
     38* WooCommerce search (premium - extension only)
     39* Gravity Forms Search (premium - extension only)
    3840* Full screen block editor killer
    3941* Block editor welcome guide remover
    4042* Live/dev site labels
    4143
    42 Remember, the browser extension it works everywhere that it can detect WordPress without needing a plugin. And it carries your preferences with you! It's WordPress, your way!
     44Remember, the browser extension it works everywhere that it can detect WordPress, without needing a plugin. And it carries your preferences with you! It's WordPress, your way!
    4345
    4446[Check out the Browser Extension and try it for free](https://turbo-admin.com/)
     
    7476If you hold Ctrl/Cmd when selecting an item it will open in a new tab/window (you may need to allow your browser to open popups).
    7577
    76 As well as commands, the plugin will also search content that is made available through the REST API (as long as the REST API can be discovered).
     78## Search modes
     79
     80As well as commands, the plugin can also search content that is made available through the REST API (as long as the REST API can be discovered).
     81
     82This is done using "search modes".
     83
     84For example, if you type "post" and then press the tab key (or type a colon) you will switch to the "post" search mode. In this mode you are searching for posts.
     85
     86Turbo Admin automatically creates search modes for any public post types on your site. It also creates the following search modes:
     87
     88* user
     89* plugin
     90* site (for WordPress Multisite sites)
     91
     92There is full documentation of search modes on [the Turbo Admin website](https://turbo-admin.com/searching.html)
    7793
    7894## Admin bar search mode
     
    169185== Changelog ==
    170186
     187= 1.12.0 =
     188* [FEATURE] Search modes
     189* [FEATURE] User search
     190* [FEATURE] Plugin search
     191* [ENHANCEMENT] Command palette core re-written to be faster, more reliable and more extensible.
     192
    171193= 1.9.0 =
    172194* [FEATURE] Admin bar search mode
  • turbo-admin/trunk/src/class-turbo-admin-palette.js

    r2703739 r2835882  
    1818
    1919import Fuse from './fuse-6.4.6.js';
    20 import TurboAdminMenuItem from './class-turbo-admin-menu-item';
    21 import ContentApi from './class-content-api.js';
     20import TurboAdminMenuItem from './types/class-turbo-admin-menu-item';
     21import ContentApi from './apis/class-content-api.js';
     22import SearchMode from './types/class-search-mode.js';
     23import ContentItem from './types/class-content-item.js';
    2224
    2325export default class TurboAdminPalette {
     
    3537        /** @type {HTMLInputElement} */
    3638        this.paletteInputElement = /** @type {HTMLInputElement} */ (document.getElementById('ta-command-palette-input'));
     39        /** @type {HTMLDivElement} */
     40        this.paletteItemsContainerElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-items-container'));
    3741        /** @type {HTMLUListElement} */
    3842        this.paletteItemsElement = /** @type {HTMLUListElement} */ (document.getElementById('ta-command-palette-items'));
     43        /** @type {HTMLDivElement} */
     44        this.paletteSubmenuContainerElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-submenu-container'));
     45        /** @type {HTMLDivElement} */
     46        this.paletteSearchModeTag = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-search-mode-tag'));
     47        /** @type {HTMLDivElement} */
     48        this.paletteSearchModeTabNotice = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-tab-notice'));
     49        /** @type {HTMLSpanElement} */
     50        this.paletteSearchModeTabNoticeText = /** @type {HTMLSpanElement} */ (document.getElementById('ta-command-palette-tab-notice-text'));
     51        /** @type {HTMLDivElement} */
     52        this.paletteNoticeElement = /** @type {HTMLDivElement} */ (document.getElementById('ta-command-palette-notice'));
     53
     54
     55        // Add a class if the menu needs refreshing with a visit to the Dashboard
     56        if (globalThis.turboAdmin.menuNeedsRefresh) {
     57            this.showPaletteNotice('Menu needs refreshing. Visit the Dashboard to refresh.');
     58        }
     59
     60        // We need this when injecting items. We use it to help generate edit URLs. Not the best way but
     61        // works for now.
     62        /** @type {HTMLUListElement} */
     63        this.profileLinkElem = document.getElementById('wp-admin-bar-edit-profile');
     64        /** @type {null|String} */
     65        this.profileLink = null;
     66        if (this.profileLinkElem) {
     67            this.profileLink = this.profileLinkElem.querySelector('a').href;
     68        }
    3969
    4070        // Get palette data
    4171        this.paletteData = paletteData;
    4272
    43         // Get post type data from API
    44         this.postTypes = [];
    45         this.fetchPostTypes();
     73        // Backup of the palette data for use when we enter a different search mode
     74        this.paletteDataBackup = null;
     75        this.paletteItemsBackup = null;
     76        this.paletteItemIndexBackup = null;
     77
     78        // Current search modes/keyword
     79        this.searchMode = null;
    4680
    4781        // paletteItems is the list of 'li' elements used to build the palette
     
    105139    }
    106140
    107     fetchPostTypes() {
    108         if (! globalThis.contentApi.active) {
    109             this.postTypes = [];
    110             return;
    111         }
    112 
    113         globalThis.contentApi.get('types').then(
    114             response => {
    115                 response.json().then(
    116                     types => {
    117                         this.postTypes = types;
    118                     }
    119                 );
    120             }
    121         );
    122     }
    123 
    124     buildPaletteItems() {
     141    inSearchMode() {
     142        return this.searchMode !== null;
     143    }
     144
     145    /**
     146     * This converts this.paletteData into a list of paletteListItems in this.paletteItems
     147     *
     148     * It also builds the itemIndex
     149     */
     150    buildPaletteItems() {
    125151        this.paletteItems = [];
    126152        this.itemIndex = {};
     
    155181    }
    156182
    157     injectContentItems(contentItems) {
     183    /**
     184     * Clears and sets the content items
     185     *
     186     * @param {ContentItem[]} contentItems
     187     */
     188    setContentItems(contentItems) {
     189        this.paletteItems = [];
     190        this.itemIndex = [];
     191        this.injectContentItems(contentItems, false);
     192    }
     193
     194    /**
     195     * Content items have:
     196     *  title
     197     *  subtype
     198     *  url
     199     *  (we should also make the sub-menu definable, but that's not done yet)
     200     *
     201     * @param {ContentItem[]} contentItems
     202     */
     203    injectContentItems(contentItems, andRunSearch = true) {
    158204        console.log('Injecting items');
    159205
    160         // We'll need this in the loop below.
    161         const profileLinkElem = document.getElementById('wp-admin-bar-edit-profile');
    162         let profileLink = null;
    163         if (profileLinkElem) {
    164             profileLink = profileLinkElem.querySelector('a').href;
    165         }
    166 
    167         // TODO: Can we not do this on every content item inject?
    168         // Check for presence of Oxygen Page builder
    169         /** @type {HTMLElement|string|Number} */
    170         let oxygenLinkElem = document.getElementById('toplevel_page_ct_dashboard_page');
    171         // Also check for a menu bar item
    172         if (! oxygenLinkElem) {
    173             oxygenLinkElem = document.getElementById('wp-admin-bar-oxygen_admin_bar_menu');
    174         }
    175         // Check to see if Oxygen link is cached
    176         if (! oxygenLinkElem) {
    177             oxygenLinkElem = Number(window.localStorage.getItem('ta-has-oxygen-builder'));
    178         }
    179         // Save Oxygen builder status
    180         window.localStorage.setItem('ta-has-oxygen-builder', Boolean(oxygenLinkElem) ? '1' : '0' );
    181 
    182206        if (contentItems.length > 0) {
    183             contentItems.forEach(item => {
    184                 const itemTitle = item.title;
    185                 // const itemTitle = item.title.rendered;
    186                 const itemType = item.subtype;
    187                 const itemUrl = item.url;
    188 
    189                 // console.log('Adding item: ' + itemTitle);
    190 
    191                 // // Check if item already exists
    192                 if (this.contentItemExists(itemUrl)) {
    193                     console.log('Not adding duplicate');
    194                     return;
     207            contentItems.forEach(this.injectItem.bind(this));
     208        }
     209
     210        if (andRunSearch) {
     211            // Reset the search to work on the new items
     212            this.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);
     213            this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map(i => i.item);
     214        }
     215
     216        this.updatePaletteItems();
     217    }
     218
     219    /**
     220     * Injects a single content item into the palette
     221     *
     222     * @param {ContentItem} item
     223     */
     224    injectItem(item) {
     225        const itemTitle = item.title;
     226        // const itemTitle = item.title.rendered;
     227        const itemType = item.subtype;
     228        const itemUrl = item.url;
     229
     230        // console.log('Adding item: ' + itemTitle);
     231
     232        // // Check if item already exists
     233        if (this.contentItemExists(itemUrl)) {
     234            console.log('Not adding duplicate');
     235            return;
     236        }
     237
     238        let title = itemTitle;
     239
     240        if (itemType) {
     241            const itemTypeName = globalThis.contentApi.postTypes[itemType] ? globalThis.contentApi.postTypes[itemType].name : itemType;
     242            title += ` (${itemTypeName})`;
     243        }
     244
     245        const li = document.createElement('li');
     246        const a = document.createElement('a');
     247        let subMenu = null;
     248
     249        // Loop over submenu items OR add link.
     250        if (item.submenuItems.length > 0) {
     251
     252            // Prepare the outer sub-menu elements
     253            subMenu = document.createElement('div');
     254            const subMenuTitle = document.createElement('div');
     255            const subMenuItems = document.createElement('ul');
     256            subMenu.classList.add('ta-submenu');
     257            subMenuTitle.classList.add('ta-submenu-title');
     258
     259            subMenuTitle.textContent = this.htmlDecode(itemTitle);
     260            subMenuItems.classList.add('ta-submenu-items');
     261            subMenu.appendChild(subMenuTitle);
     262
     263            for (let i = 0; i < item.submenuItems.length; i++) {
     264                const subMenuItem = item.submenuItems[i]
     265                // TODO: Abstract this so sub-menus can be defined by plugins?
     266                const subMenuListItem = document.createElement('li');
     267                const subMenuLink = document.createElement('a');
     268                subMenuLink.innerText = subMenuItem.title;
     269                subMenuLink.href = subMenuItem.url;
     270                for (let a = 0; a < subMenuItem.attributes.length; a++) {
     271                    subMenuLink.setAttribute(
     272                        subMenuItem.attributes[a].name,
     273                        subMenuItem.attributes[a].value
     274                    )
    195275                }
    196 
    197                 const itemTypeName = this.postTypes[itemType] ? this.postTypes[itemType].name : itemType;
    198                 const title = `${itemTitle} (${itemTypeName})`;
    199 
    200                 const li = document.createElement('li');
    201                 const a = document.createElement('a');
    202                 const subMenu = document.createElement('div');
    203                 const subMenuTitle = document.createElement('div');
    204                 const subMenuItems = document.createElement('ul');
    205                 subMenu.classList.add('ta-submenu');
    206                 subMenuTitle.classList.add('ta-submenu-title');
    207 
    208                 subMenuTitle.textContent = this.htmlDecode(itemTitle);
    209                 subMenuItems.classList.add('ta-submenu-items');
    210                 subMenu.appendChild(subMenuTitle);
    211                 subMenu.appendChild(subMenuItems);
    212 
    213                 const subMenuItem1 = document.createElement('li');
    214                 const subMenuLink1 = document.createElement('a');
    215                 subMenuLink1.innerText = "View";
    216                 subMenuLink1.href = itemUrl;
    217                 subMenuItem1.appendChild(subMenuLink1);
    218                 subMenuItems.appendChild(subMenuItem1);
    219 
    220                 if (profileLink) {
    221                     // Need to get edit URL. This seems like the best way for now.
    222                     const editLink = profileLink.replace('profile.php', `post.php?post=${item.id}&action=edit`);
    223 
    224                     const subMenuItem2 = document.createElement('li');
    225                     const subMenuLink2 = document.createElement('a');
    226                     subMenuLink2.innerText = "Edit";
    227                     subMenuLink2.href = editLink;
    228                     subMenuItem2.appendChild(subMenuLink2);
    229                     subMenuItems.appendChild(subMenuItem2);
    230                 }
    231 
    232                 if (oxygenLinkElem) {
    233                     // Oxygen Edit Links are like: https://example.com.com/?page_id=26&ct_builder=true&ct_inner=true
    234                     const oxygenLink = globalThis.taWp.home + `?page_id=${item.id}&ct_builder=true&ct_inner=true`;
    235 
    236                     const subMenuItem3 = document.createElement('li');
    237                     const subMenuLink3 = document.createElement('a');
    238                     subMenuLink3.innerText = "Edit with Oxygen";
    239                     subMenuLink3.href = oxygenLink;
    240                     subMenuItem3.appendChild(subMenuLink3);
    241                     subMenuItems.appendChild(subMenuItem3);
    242                 }
    243 
    244                 const subMenuItem3 = document.createElement('li');
    245                 const subMenuLink3 = document.createElement('a');
    246                 subMenuLink3.innerText = "Copy link";
    247                 // Because this is an href we're setting it gets URI encoded!
    248                 subMenuLink3.href = itemUrl;
    249                 subMenuLink3.setAttribute('data-action', 'clipboard');
    250                 subMenuItem3.appendChild(subMenuLink3);
    251                 subMenuItems.appendChild(subMenuItem3);
    252 
    253 
    254                 li.classList.add('ta-has-child-menu');
    255 
    256                 li.appendChild(a);
    257                 li.appendChild(subMenu);
    258 
    259                 a.href = itemUrl;
    260                 a.innerHTML = title;
    261                 this.addPaletteListItem(li);
    262             })
    263         }
    264 
    265         // Reset the search to work on the new items
    266         this.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);
    267         this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map(i => i.item);
    268 
    269         this.updatePaletteItems();
     276                subMenuListItem.appendChild(subMenuLink);
     277                subMenuItems.appendChild(subMenuListItem);
     278            }
     279
     280            // Add the sub-menu items UL to the sub-menu element.
     281            subMenu.appendChild(subMenuItems);
     282
     283            li.classList.add('ta-has-child-menu');
     284        }
     285
     286        a.href = itemUrl;
     287        a.innerHTML = title;
     288
     289        li.appendChild(a);
     290        if (subMenu !== null) {
     291            li.appendChild(subMenu);
     292        }
     293
     294        this.addPaletteListItem(li);
    270295    }
    271296
     
    285310                this.showPalette();
    286311            }
     312            return;
    287313        }
    288314
     
    290316            if (this.isSubMenuOpen()){
    291317                this.closeSubMenu();
     318            } else if (this.inSearchMode()) {
     319                this.leaveSearchMode();
    292320            } else {
    293321                this.hidePalette();
    294322            }
     323            return;
    295324        }
    296325
     
    320349    }
    321350
     351    /*
     352     * Adds the tab hint for a keyword once it has been typed.
     353     */
     354    maybeHighlightInputKeyword(newKey) {
     355        // Do nothing if we are in a search-mode
     356        if (this.inSearchMode()) {
     357            return;
     358        }
     359
     360        // This is fired on "keyDown", so the value isn't update with the new key yet.
     361        // But don't do this for special keys, and catch backspace too.
     362        let newInputValue = this.paletteInputElement.value;
     363        if (newKey.length === 1) {
     364            newInputValue += newKey;
     365        }
     366        if (newKey === 'Backspace') {
     367            newInputValue = newInputValue.slice(0, -1);
     368        }
     369        // console.log(`Checking palette input value ${newInputValue} for keyword`);
     370        if (this.isKeyword(newInputValue)) {
     371            this.paletteSearchModeTabNoticeText.innerText = `Search for ${newInputValue}`;
     372            this.paletteSearchModeTabNotice.classList.add('active');
     373        } else {
     374            this.unhighlightInputKeyword();
     375        }
     376    }
     377
     378    unhighlightInputKeyword() {
     379        this.paletteSearchModeTabNotice.classList.remove('active');
     380    }
     381
    322382    async debouncedPaletteSearchAndUpdate() {
    323         // If search string is not long enough for content search, then
    324         // run without debounce.
    325         if (
    326             ( this.paletteInputElement.value !== '' && this.paletteInputElement.value.length <= 2)
    327             || this.postTypes === [] ) {
     383        // If we're not in a search mode then search immediately
     384        if (! this.inSearchMode()) {
    328385            this.debounceTimeout = null;
    329386            await this.paletteSearchAndUpdate();
    330387            return;
    331388        }
     389
    332390        // If timer is null, reset it to 500ms and run your functions.
    333391        // Otherwise, wait until timer is cleared
    334         if (!this.debounceTimeout) {
    335             this.debounceTimeout = setTimeout(async function () {
    336                 // Reset timeout
    337                 this.debounceTimeout = null;
    338 
    339                 // Run the search function
    340                 await this.paletteSearchAndUpdate();
    341             }.bind(this), 750);
    342         }
     392
     393        // Cancel the existing timeout
     394        clearTimeout(this.debounceTimeout)
     395
     396        this.debounceTimeout = setTimeout(async function () {
     397            // Reset timeout
     398            this.debounceTimeout = null;
     399
     400            // Run the search function
     401            await this.paletteSearchAndUpdate();
     402        }.bind(this), 750);
     403    }
     404
     405    /**
     406     * Check if a string is a search mode keyword
     407     *
     408     * @param {string} inputString
     409     * @returns {boolean}
     410     */
     411    isKeyword(inputString) {
     412        return Object.keys(globalThis.turboAdmin.searchModes).includes(inputString);
     413    }
     414
     415    /**
     416     * Show the palette notice with the specified text
     417     *
     418     * @param {string} text
     419     */
     420    showPaletteNotice(text) {
     421        this.paletteNoticeElement.classList.add('active');
     422        this.paletteNoticeElement.innerText = text;
     423    }
     424
     425    /**
     426     * Hide the palette notice
     427     */
     428    hidePaletteNotice() {
     429        this.paletteNoticeElement.classList.remove('active');
    343430    }
    344431
     
    361448        }
    362449        if (e.code === 'Enter' && this.paletteShown()) {
     450            e.preventDefault();
    363451            this.doAction(this.metaPressed(e));
    364452            return;
    365453        }
     454
     455        /*
     456         * Only the actions above can be done in sub-menus.
     457         */
    366458        if (this.isSubMenuOpen()) {
    367459            return;
    368460        }
     461
     462        /*
     463         * Check for a keyword being typed and add a UI hint.
     464         */
     465        this.maybeHighlightInputKeyword(e.key);
     466
     467        /*
     468         * Tabbing looks for a search mode keyword.
     469         */
     470        if (! this.inSearchMode() && (e.code === 'Tab' || e.key === ':')) {
     471            console.log('Checking for search mode');
     472            let inputValue = this.paletteInputElement.value;
     473            if (this.isKeyword(inputValue)) {
     474                console.log('Found search mode ' + inputValue)
     475                e.preventDefault();
     476                // TODO: Work on this.
     477                await this.enterSearchMode(
     478                    globalThis.turboAdmin.searchModes[inputValue]);
     479                return;
     480            }
     481        }
     482
     483        /*
     484         * Backspace may exit us from a search mode
     485         */
     486        if (this.inSearchMode() && e.code === 'Backspace' && this.paletteInputElement.value === '') {
     487            e.preventDefault();
     488            this.leaveSearchMode();
     489            return;
     490        }
     491
    369492        await this.debouncedPaletteSearchAndUpdate();
    370493    }
    371494
     495    /**
     496     * Puts the palette into a specific search mode - used when a keyword is selected
     497     *
     498     * @param {SearchMode} searchMode
     499     */
     500    async enterSearchMode(searchMode) {
     501        console.log('Entering search mode for keyword ' + searchMode.keyword);
     502        this.backupPaletteData();
     503
     504        this.paletteData = [];
     505        this.paletteItems = [];
     506        this.itemIndex = [];
     507
     508        // Remove the notice if it's there
     509        this.hidePaletteNotice();
     510
     511        this.searchMode = searchMode;
     512        this.paletteInputElement.value = '';
     513        this.addSearchModeTag(searchMode.displayName);
     514        this.unhighlightInputKeyword();
     515        this.updatePaletteItems();
     516        // This is similar to code in paletteSearch - maybe we could extract/abstract it?
     517        if (searchMode.defaultItemsCallback !== null) {
     518            this.paletteInnerElement.classList.add('loading');
     519            const results = await searchMode.defaultItemsCallback();
     520            this.setContentItems(results);
     521            // this.injectContentItems(results);
     522            this.paletteInnerElement.classList.remove('loading');
     523        }
     524    }
     525
     526    /**
     527     * Leaves the current search mode
     528     */
     529    leaveSearchMode() {
     530        const searchMode = this.searchMode;
     531        // It's important what we set this to - see inSearchMode()
     532        this.searchMode = null;
     533        this.removeSearchModeTag();
     534        this.restorePaletteData();
     535        this.paletteInputElement.value = searchMode.keyword;
     536        this.maybeHighlightInputKeyword('');
     537        this.paletteSearchAndUpdate();
     538    }
     539
     540    /**
     541     * Backups up the palette data to a local variable so that it can be
     542     * restored later.
     543     */
     544    backupPaletteData() {
     545        this.paletteDataBackup = this.paletteData;
     546        this.paletteItemsBackup = this.paletteItems;
     547        this.paletteItemIndexBackup = this.itemIndex;
     548    }
     549
     550    /**
     551     * Restores the save palette data - does not rebuild anything
     552     */
     553    restorePaletteData() {
     554        this.paletteData = this.paletteDataBackup;
     555        this.paletteItems = this.paletteItemsBackup;
     556        this.itemIndex = this.paletteItemIndexBackup;
     557    }
     558
     559    /**
     560     * Adds the search mode tag with the specified title.
     561     *
     562     * @param {string} title
     563     */
     564    addSearchModeTag(title) {
     565        this.paletteSearchModeTag.classList.add('active');
     566        this.paletteSearchModeTag.innerText = title;
     567    }
     568
     569    /**
     570     * Removes the search mode tag
     571     */
     572    removeSearchModeTag() {
     573        this.paletteSearchModeTag.classList.remove('active');
     574    }
     575
     576    isPaletteOpen() {
     577        return this.paletteElement?.classList.contains('active');
     578    }
     579
    372580    showPalette() {
    373         this.paletteInputElement.value = '';
    374         this.paletteItemsElement.scrollTop = 0;
     581        // Bail if already shown (this can be triggered by a focus event)
     582        if (this.isPaletteOpen()) {
     583            return;
     584        }
     585
     586        this.paletteInputElement.value = '';
     587        this.paletteInputElement?.focus();
    375588        this.paletteElement?.classList.add('active');
    376         this.paletteInputElement?.focus();
     589        // This is needed in admin-bar mode otherwise it gets a weird already-scrolled thing when
     590        // the palette opens.
     591        setTimeout(() => this.paletteItemsElement.scrollTop = 0, 100);
    377592    }
    378593
     
    385600            this.closeSubMenu();
    386601        }
     602        if (this.searchMode !== null) {
     603            this.leaveSearchMode();
     604        }
    387605    }
    388606
     
    413631    setSelectedElement() {
    414632        if (this.isSubMenuOpen()) {
    415             this.paletteItemsElement?.querySelectorAll('.ta-submenu.active li.selected')?.forEach(e => e.classList.remove('selected'));
     633            this.paletteSubmenuContainerElement?.querySelectorAll('.ta-submenu li.selected')?.forEach(e => e.classList.remove('selected'));
    416634            this.selectedSubItem.classList.add('selected');
    417635        } else {
     
    489707
    490708    openSubMenu(subMenuElement) {
     709        this.paletteSubmenuContainerElement.replaceChildren(subMenuElement);
    491710        // Set height in case main menu is smaller than sub menu
    492         const subMenuHeight = subMenuElement.offsetHeight;
    493         this.paletteItemsElement.style.minHeight = subMenuHeight + "px";
    494         subMenuElement.classList.add('active');
    495 
     711        const subMenuHeight = this.paletteSubmenuContainerElement.offsetHeight;
     712        this.paletteItemsContainerElement.style.minHeight = subMenuHeight + "px";
     713        this.paletteSubmenuContainerElement.classList.add('active');
    496714
    497715        this.selectedSubItem = subMenuElement.querySelector('li');
     
    508726            subMenuElement = document.querySelector('.ta-submenu.active');
    509727        }
    510         subMenuElement.classList.remove('active');
     728        this.paletteSubmenuContainerElement.classList.remove('active');
    511729        this.selectedSubItem.classList.remove('active');
    512         this.paletteItemsElement.style.minHeight = 'auto';
     730        this.paletteItemsContainerElement.style.minHeight = 'auto';
    513731        this.selectedSubItem = null;
    514732        this.openedSubMenu = null;
     
    536754        const url = link.href;
    537755
     756        // link.href will be interpolated by the browser, so if it's empty it will be the current page
     757        // use getAttribute instead to work out if its empty
     758        if (link.getAttribute('href') === '') {
     759            return;
     760        }
     761
    538762        if ('clipboard' === link.dataset.action) {
    539763            navigator.clipboard.writeText(url);
     
    561785        // const response = await globalThis.contentApi.get('posts', { search: this.paletteInputElement.value, per_page: 100, status: ['publish', 'future', 'draft', 'pending', 'private'] });
    562786
    563         this.buildPaletteItems();
    564 
    565         if (this.paletteInputElement.value !== '') {
    566             // Reset the search to work on the new items
    567             this.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);
    568             this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map(i => i.item);
    569         }
    570 
     787        if (! this.searchMode) {
     788            this.buildPaletteItems();
     789
     790            if (this.paletteInputElement.value !== '') {
     791                // Reset the search to work on the new items
     792                this.paletteFuse = new Fuse(this.paletteItems, this.paletteFuseOptions);
     793                this.paletteItems = this.paletteFuse.search(this.paletteInputElement.value).map(i => i.item);
     794            }
     795            return;
     796        }
     797
     798        if (this.paletteInputElement.value.length === 0) {
     799            this.paletteInnerElement.classList.add('loading');
     800            let results = [];
     801            if (this.searchMode.defaultItemsCallback !== null) {
     802                results = await this.searchMode.defaultItemsCallback();
     803            }
     804            this.setContentItems(results);
     805            // this.injectContentItems(results);
     806            this.paletteInnerElement.classList.remove('loading');
     807        } else {
     808            // This is copied to enterSearchMode. Should probably be extracted.
     809            this.paletteInnerElement.classList.add('loading');
     810            const results = await this.searchMode.searchCallback(this.paletteInputElement.value);
     811            this.setContentItems(results);
     812            // this.injectContentItems(results);
     813            this.paletteInnerElement.classList.remove('loading');
     814        }
     815
     816        /**
     817         * OLD CODE BELOW
     818         */
    571819        // Content search - don't search everything!
    572         if (globalThis.contentApi.active && this.postTypes !== [] && this.paletteInputElement.value.length > 2) {
    573             this.paletteInnerElement.classList.add('loading');
    574 
    575             globalThis.contentApi.getPosts(this.paletteInputElement.value)
    576                 .then(
    577                     results => {
    578                             this.injectContentItems(results);
    579                             this.paletteInnerElement.classList.remove('loading');
    580                     }
    581                 )
    582         }
     820        // if (globalThis.contentApi.active && this.postTypes !== [] && this.paletteInputElement.value.length > 2) {
     821        //     this.paletteInnerElement.classList.add('loading');
     822
     823        //     globalThis.contentApi.getPosts(this.paletteInputElement.value)
     824        //         .then(
     825        //             results => {
     826        //                     this.injectContentItems(results);
     827        //                     this.paletteInnerElement.classList.remove('loading');
     828        //             }
     829        //         )
     830        // }
    583831    }
    584832
  • turbo-admin/trunk/src/class-turbo-admin-wp-notices.js

    r2703739 r2835882  
    161161
    162162        noticesToHide.forEach(notice => {
    163             // Add 'inline' class otherwise WordPress might move them around!
    164             notice.classList.add('inline');
    165163            // See Toolbelt's implementation: https://github.com/BinaryMoon/wp-toolbelt/blob/dev/modules/tidy-notifications/src/js/script.js
    166164            noticesPanelInner.append(notice);
  • turbo-admin/trunk/src/class-turbo-admin.js

    r2703739 r2835882  
    4343 * }
    4444 */
     45
    4546import TurboAdminPalette from './class-turbo-admin-palette.js';
    46 import TurboAdminMenuItem from './class-turbo-admin-menu-item.js';
    47 import Acf from './class-acf.js';
    48 import TurboAdminWpBlockEditorFullscreenKill from './class-turbo-admin-wp-block-editor-fullscreen-kill.js';
    49 import TurboAdminWpBlockEditorWelcomeGuideKill from './class-turbo-admin-wp-block-editor-welcome-guide-kill.js';
     47import TurboAdminMenuItem from './types/class-turbo-admin-menu-item.js';
     48import SearchMode from './types/class-search-mode.js';
     49import TurboAdminPlugin from './types/class-turbo-admin-plugin.js';
     50import Acf from './plugins/class-acf.js';
     51// import TurboAdminWpBlockEditorFullscreenKill from './class-turbo-admin-wp-block-editor-fullscreen-kill.js';
     52// import TurboAdminWpBlockEditorWelcomeGuideKill from './class-turbo-admin-wp-block-editor-welcome-guide-kill.js';
    5053import TurboAdminWpNotices from './class-turbo-admin-wp-notices.js';
    5154import TurboAdminListTableShortcuts from './class-list-table-shortcuts.js';
    52 import TurboAdminBarkeeper from './class-turbo-admin-barkeeper.js';
     55import TurboAdminBarkeeper from './plugins/class-turbo-admin-barkeeper.js';
     56import TurboAdminContentSearch from './plugins/class-turbo-admin-content-search.js';
     57import TurboAdminPluginSearch from './plugins/class-turbo-admin-plugins.js';
     58import TurboAdminUserSearch from './plugins/class-turbo-admin-users.js';
     59// import TurboAdminWoocommerce from './plugins/class-turbo-admin-woocommerce.js';
     60// import TurboAdminGravityForms from './plugins/class-turbo-admin-gravity-forms.js';
     61import TurboAdminMUSites from './plugins/class-turbo-admin-mu-sites.js';
     62import TurboAdminOxygenBuilder from './plugins/class-turbo-admin-oxygen-buillder.js';
    5363
    5464export default class TurboAdmin {
    5565
     66    /**
     67     * @param {*} options
     68     * @returns {TurboAdmin}
     69     */
    5670    constructor(options) {
     71        // Sometimes we get a second copy of TA running, like if the plugin is running too.
     72        // Is this case we want to skip the initialisation.
     73        this.doInit = true;
     74
    5775        if (document.getElementById('ta-command-palette-container')) {
    5876            console.log('TurboAdmin already initialised - I won\'t make a second copy!');
     77            this.doInit = false;
     78            return globalThis.turboAdmin;
     79        }
     80
     81        this.options = options;
     82        this.plugins = {};
     83
     84        // TODO: Something? What should this type be?
     85        this.searchModes = {};
     86
     87        // On the front end we set this if there is no saved menu.
     88        this.menuNeedsRefresh = false;
     89    }
     90
     91    /**
     92     * Perform initialization - this is all the things that do not need APIs to
     93     * get set up.
     94     */
     95    async init() {
     96        if (! this.doInit) {
    5997            return;
    6098        }
    6199
    62         this.options = options;
    63     }
    64 
    65     async init() {
     100        // Register all the plugins
     101        new TurboAdminBarkeeper();
     102        new TurboAdminContentSearch();
     103        new TurboAdminPluginSearch();
     104        new TurboAdminUserSearch();
     105        // new TurboAdminWoocommerce();
     106        // new TurboAdminGravityForms();
     107        new TurboAdminMUSites();
     108        new TurboAdminOxygenBuilder();
     109
    66110        // Grab the global Wp object instance
    67111        this.wp = globalThis.taWp;
    68112
    69113        this.menu = [];
     114
    70115        // Check for saved menu when on front-end
    71116        if (! this.wp.isBackend) {
     
    75120            // refresh the menu.
    76121            if (! this.wp.siteChanged) {
    77                 // Get from localStorage
    78                 const savedMenu = window.localStorage.getItem('ta-palette-data');
    79 
    80                 if (null !== savedMenu) {
    81                     // Check for .logged-in class on body
    82                     if (document.body.classList.contains('logged-in')) {
    83                         // If still logged in merge (?) the items
     122                // Check for .logged-in class on body - if logged in, we can use the saved menu,
     123                // if it exists.
     124                if (document.body.classList.contains('logged-in')) {
     125                    // Get from localStorage
     126                    const savedMenu = window.localStorage.getItem('ta-palette-data');
     127
     128                    // This attempts to see if we have cached items from the back-en
     129                    if (null === savedMenu) {
     130                        this.menuNeedsRefresh = true;
     131                    } else {
    84132                        this.menu = JSON.parse(savedMenu);
     133                        // Check if there is no "Media" item  - this should ONLY be in the back-end
     134                        if (! this.menu.some(item => item.action.endsWith('upload.php'))) {
     135                            this.menuNeedsRefresh = true;
     136                        }
     137                        // Merge (?) the items?
    85138                    }
    86139                }
     
    123176        // Initialise controls on the palette
    124177        this.turboAdminPalette = new TurboAdminPalette(this.menu, this.options);
    125 
    126         if (true === this.options['block-editor-fullscreen-disable']) {
    127             // Initialise fullscreen kill
    128             this.turboAdminFullscreenKill = new TurboAdminWpBlockEditorFullscreenKill();
    129         }
    130 
    131         if (true === this.options['block-editor-welcome-screen-kill']) {
    132             this.turboAdminWelcomeKill = new TurboAdminWpBlockEditorWelcomeGuideKill();
    133         }
     178    }
     179
     180    /**
     181     * These are initialization steps that DO needs APIs to be set up.
     182     */
     183    activatePlugins() {
     184        // Initialize all plugins
     185        Object.keys(this.plugins).forEach( plugin => {
     186            if (this.plugins[plugin].shouldActivate()) {
     187                this.plugins[plugin].activate();
     188            }
     189        })
     190
     191        // if (true === this.options['block-editor-fullscreen-disable']) {
     192        //     // Initialise fullscreen kill
     193        //     this.turboAdminFullscreenKill = new TurboAdminWpBlockEditorFullscreenKill();
     194        // }
     195
     196        // if (true === this.options['block-editor-welcome-screen-kill']) {
     197        //     this.turboAdminWelcomeKill = new TurboAdminWpBlockEditorWelcomeGuideKill();
     198        // }
    134199
    135200        if (true === this.options['list-table-keyboard-shortcuts']) {
    136201            this.turboAdminListTableShortcuts = new TurboAdminListTableShortcuts();
    137         }
    138 
    139         if (true === this.options['barkeeper']) {
    140             // In the plugin, barkeeper-state will be in... local storage(?)
    141             if ('object' !== typeof(browser)) {
    142                 this.options['barkeeper-state'] = window.localStorage.getItem('turboAdminBarkeeperState');
    143             }
    144             this.turboAdminBarkeeper = new TurboAdminBarkeeper(this.options['barkeeper-state']);
    145202        }
    146203
     
    151208    }
    152209
     210    /**
     211     * True if the plugin has been activated
     212     *
     213     * @param {string} name Name of the plugin to check for
     214     * @returns {boolean}
     215     */
     216    hasActivatedPlugin(name) {
     217        return Object.keys(this.plugins).includes(name) &&
     218            this.plugins[name].activated;
     219    }
     220
     221    /**
     222     * Gather the WordPress dashboard admin (sidebar) menu items
     223     *
     224     * @returns { TurboAdminMenuItem[] }
     225     */
    153226    getMenu() {
    154227        const items = [];
     
    184257    }
    185258
     259    /**
     260     * Adds additional menu items passed in by configuration to the
     261     * menu items list.
     262     */
    186263    addAdditionalMenuItems() {
    187264
     
    207284
    208285        // Get passed-in extraItems
     286        // Technically this is an array of {ItemDefintion} but more work needed to make that happen.
    209287        let extraItems = this.options.extraItems ?? [];
     288
     289        // Get any extra items defined by plugins
     290        const pluginKeys = Object.keys(this.plugins);
     291
     292        for (let i=0; i < pluginKeys.length; i++) {
     293            extraItems = extraItems.concat(this.plugins[pluginKeys[i]].getAdditionalItemDefinitions());
     294        }
    210295
    211296        // Merge in defaults
     
    288373                    'itemUrlFunction': (element) => element.href
    289374                },
    290                 {
    291                     'detectType': 'dom',
    292                     'detectSelector': '#wp-admin-bar-my-sites #wp-admin-bar-my-sites-list .ab-submenu a',
    293                     'itemTitleFunction': (element) => "Sites: " + element.closest('.menupop').querySelector('a').innerText + ' - ' + element.innerText,
    294                     'itemUrlFunction': (element) => element.href
    295                 },
    296                 // Oxygen builder items
    297                 {
    298                     'detectType': 'dom',
    299                     'detectSelector': '#ct-edit-template-builder',
    300                     'itemTitleFunction': () => 'Edit with Oxygen',
    301                     'itemUrlFunction': (element) => element.href,
    302                     'noCache': true
    303                 },
    304                 // It's worth noting that the Oxygen Builder doesn't use a /wp-admin URL
    305                 // and so kinda appears to Turbo Admin to be a "front-end" page and it
    306                 // doesn't refresh the menu items.
    307                 {
    308                     'detectType': 'dom',
    309                     'detectSelector': '.oxygen-back-to-wp-menu .oxygen-toolbar-button-dropdown a:not(:last-of-type)',
    310                     'itemTitleFunction': (element) => 'Back to WP: ' + element.textContent,
    311                     'itemUrlFunction': (element) => {
    312                         if (element.href) {
    313                             return element.href;
    314                         } else {
    315                             let url = new URL(window.location.href);
    316                             return url.origin + url.pathname;
    317                         }
    318                     },
    319                     'noCache': true
    320                 }
    321375            ]
    322376        );
     
    359413    }
    360414
     415    /**
     416     * Builds the palette HTML and adds it to the DOM.
     417     */
    361418    addPalette() {
    362419        const container = document.createElement('div');
     
    365422        const palette = document.createElement('div');
    366423        palette.id = 'ta-command-palette';
     424        // Palette notice
     425        const paletteNotice = document.createElement('div');
     426        paletteNotice.id = 'ta-command-palette-notice';
     427        // Tab notice
     428        const tabNotice = document.createElement('div');
     429        tabNotice.id = 'ta-command-palette-tab-notice';
     430        // Tab notice text
     431        const tabNoticeText = document.createElement('span');
     432        tabNoticeText.id = 'ta-command-palette-tab-notice-text';
     433        // Tab notice "button"
     434        const tabNoticeButton = document.createElement('span');
     435        tabNoticeButton.id = 'ta-command-palette-tab-notice-button';
     436        tabNoticeButton.innerText = 'Tab';
    367437        // Input field
    368438        const input = document.createElement('input');
     
    372442        // Set this to stop stuff trying to fill it.
    373443        input.setAttribute('autocomplete', 'off');
     444        // Search mode tag
     445        const searchModeTag = document.createElement('div');
     446        searchModeTag.id = 'ta-command-palette-search-mode-tag';
     447        // List container (needed to contain the main list and the submenu list)
     448        const listContainer = document.createElement('div');
     449        listContainer.id = "ta-command-palette-items-container";
    374450        // List
    375451        const list = document.createElement('ul');
    376452        list.id = "ta-command-palette-items";
     453        // Sub-menu list
     454        const submenuContainer = document.createElement('div');
     455        submenuContainer.id = "ta-command-palette-submenu-container";
    377456        // Join it all up
    378457        container.appendChild(palette);
     458        palette.appendChild(searchModeTag);
     459        palette.appendChild(paletteNotice);
     460        tabNotice.appendChild(tabNoticeText);
     461        tabNotice.appendChild(tabNoticeButton);
     462        palette.appendChild(tabNotice);
    379463        palette.appendChild(input);
    380         palette.appendChild(list);
     464        listContainer.appendChild(list);
     465        listContainer.appendChild(submenuContainer);
     466        palette.appendChild(listContainer);
    381467
    382468        if (document.getElementById('wpadminbar') && this.options['admin-bar-search'] === true) {
     
    395481            placeholder.addEventListener('click', e => input.focus());
    396482
    397             palette.insertBefore( placeholder, list );
     483            palette.insertBefore( placeholder, listContainer );
    398484        } else {
    399485            // Container
     
    402488    }
    403489
     490    /**
     491     * Register a plugin with Turbo Admin
     492     *
     493     * @param {TurboAdminPlugin} plugin
     494     */
     495    registerPlugin(plugin) {
     496        console.log('Registering plugin ' + plugin.name);
     497        this.plugins[plugin.name] = plugin;
     498    }
     499
     500    /**
     501     * Register a palette search mode and its associated plugin
     502     *
     503     * this is usually bound to the searchMode, so
     504     *
     505     * @param {SearchMode} searchMode
     506     */
     507    registerSearchMode(searchMode) {
     508        console.log('Registering search mode with keyword ' + searchMode.keyword);
     509        // Don't use `this` as we are bound!
     510        globalThis.turboAdmin.searchModes[searchMode.keyword] = searchMode;
     511    }
     512
     513    /**
     514     * Returns a string representation of the palette's keyboard shortcut
     515     *
     516     * @returns { String }
     517     */
    404518    buildShortcutKeysString () {
    405519        let keysString = '';
     
    418532            keysString += 'Shift-';
    419533        }
    420         keysString += shortcut.key.toUpperCase();
     534        keysString += shortcut.key;
    421535        return keysString;
    422536    }
  • turbo-admin/trunk/src/main.js

    r2703739 r2835882  
    11import TurboAdmin from './class-turbo-admin.js';
    2 import ContentApi from './class-content-api.js';
     2import ContentApi from './apis/class-content-api.js';
    33import Wp from './class-wp.js';
    44import TurboAdminWpNotices from './class-turbo-admin-wp-notices.js';
     5import WoocommerceApi from './apis/class-woocommerce-api.js';
     6import GravityFormsApi from './apis/class-gravity-forms-api.js';
    57
    68const taStorageKey = 'turbo-admin-settings';
     9
     10// Use this to clear storage
     11// browser.storage.local.remove(taStorageKey).then();
    712
    813// Note that in the extension, the globalThis is not the browser's global scope,
     
    1015async function taInit(settings) {
    1116
     17    if (typeof(globalThis.turboAdmin) !== 'undefined') {
     18        // Already initialised for some reason
     19        return;
     20    }
    1221    globalThis.turboAdmin = null;
    1322
     
    1928
    2029    globalThis.turboAdminOptions = settings[taStorageKey];
     30
     31    console.log('Preparing Turbo Admin');
    2132
    2233    // Get Wp stuff ready
     
    3142    globalThis.contentApi = new ContentApi();
    3243    await globalThis.contentApi.discoverApiRoot();
     44    await globalThis.contentApi.discoverPostTypes();
     45    globalThis.woocommerceApi = new WoocommerceApi();
     46    globalThis.gravityFormsApi = new GravityFormsApi();
    3347
    3448    console.log('Turbo Admin: Content API is initialised');
    3549
    3650    globalThis.turboAdmin = new TurboAdmin(globalThis.turboAdminOptions);
     51    await globalThis.turboAdmin.init();
    3752
    38     await globalThis.turboAdmin.init();
     53
     54
     55    // This needs all the APIs to be ready
     56    await globalThis.turboAdmin.activatePlugins();
    3957
    4058    if (settings[taStorageKey]['hide-notices']) {
  • turbo-admin/trunk/turbo-admin.css

    r2703739 r2835882  
    3939    top: calc( 10vh + 20px );
    4040    left: 50%;
    41     overflow: hidden;
     41    /* overflow: hidden; */
     42    overflow: visible;
    4243    transform: translateX(-50%);
    4344    opacity: 0;
    4445    transition: top 0.3s, opacity 0.3s;
     46    -webkit-font-smoothing: subpixel-antialiased; /* This normalises how the front and back-ends look */
    4547}
    4648
     
    5052}
    5153
    52 #ta-command-palette-input {
     54/*
     55 * We need to override "#wpadminbar *" in admin-bar mode, so many styles have a #wpadminbar prefix
     56 * as well as a regular selector.
     57 */
     58#ta-command-palette-tab-notice,
     59#wpadminbar #ta-command-palette-tab-notice {
     60    display: block;
     61    color: white;
     62    position: absolute;
     63    right: 24px;
     64    font-size: 12px;
     65    line-height: 1;
     66    top: 29px;
     67    opacity: 0;
     68    transition: opacity 0.3s;
     69    z-index: 20;
     70}
     71
     72#ta-command-palette-tab-notice.active,
     73#wpadminbar #ta-command-palette-tab-notice.active {
     74    opacity: 1;
     75}
     76
     77#ta-command-palette-tab-notice-button,
     78#wpadminbar #ta-command-palette-tab-notice-button {
     79    display: inline-block;
     80    color: white;
     81    border: 1px solid white;
     82    position: relative;
     83    font-size: 12px;
     84    border-radius: 4px;
     85    padding: 2px 4px;
     86    margin-left: 6px;
     87}
     88
     89#ta-command-palette-search-mode-tag,
     90#wpadminbar #ta-command-palette-search-mode-tag,
     91#ta-command-palette-notice,
     92#wpadminbar #ta-command-palette-notice {
     93    color: white;
     94    font-size: 16px;
     95    border-radius: 6px;
     96    background-color:rgb(51,51,51);
     97    position: absolute;
     98    left: 20px;
     99    top: 16px;
     100    padding: 4px 8px;
     101    line-height: 1;
     102    opacity: 0;
     103    transition: opacity 0.3s, top 0.3s, transform 0.3s;
     104}
     105
     106#ta-command-palette-notice,
     107#wpadminbar #ta-command-palette-notice {
     108    top: 16px;
     109    left: auto;
     110    right: 20px;
     111}
     112
     113#ta-command-palette-search-mode-tag.active,
     114#ta-command-palette-notice.active {
     115    top: -18px;
     116    left: 20px;
     117    padding: 6px 10px;
     118}
     119
     120#ta-command-palette-notice.active {
     121    left: auto;
     122    right: 20px;
     123}
     124
     125#ta-command-palette-search-mode-tag.active,
     126#ta-command-palette-notice.active,
     127#wpadminbar #ta-command-palette-search-mode-tag.active,
     128#wpadminbar #ta-command-palette-notice.active {
     129    opacity: 1;
     130}
     131
     132#wpadminbar #ta-command-palette-notice {
     133    font-size: 13px;
     134    top: 27px;
     135    right: 0;
     136}
     137
     138#wpadminbar #ta-command-palette-search-mode-tag {
     139    font-size: 14px;
     140    top: 2px;
     141    left: 0;
     142    transform: translateX( -100% );
     143    background-color: #666;
     144}
     145#wpadminbar #ta-command-palette-search-mode-tag:before {
     146    content: 'Search for ';
     147}
     148#wpadminbar #ta-command-palette-search-mode-tag.active {
     149    top: 2px;
     150    transform: translateX( calc( -100% - 5px ) );
     151    opacity: 1;
     152}
     153
     154
     155#ta-command-palette-input,
     156#wpadminbar #ta-command-palette-input {
    53157    font-family: inherit;
    54158    background-color: #333;
     
    63167    color: #FFF;
    64168    outline: none;
     169    z-index: 10; /* To hide the search-mode tag */
    65170}
    66171
     
    74179}
    75180
    76 #ta-command-palette:after {
     181#ta-command-palette:after,
     182#wpadminbar #ta-command-palette:after {
    77183    display: none;
    78184    content: '';
    79185    position: absolute;
     186    z-index: 20;
    80187    top: 28px;
    81188    right: 24px;
     
    90197}
    91198
    92 #ta-command-palette.loading:after {
     199#ta-command-palette.loading:after,
     200#wpadminbar #ta-command-palette.loading:after {
    93201    background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg' data-reactroot=''%3E%3Cpath fill='white' d='M12 2C11.1716 2 10.5 2.67157 10.5 3.5C10.5 4.32843 11.1716 5 12 5C12.8284 5 13.5 4.32843 13.5 3.5C13.5 2.67157 12.8284 2 12 2Z' clip-rule='evenodd' fill-rule='evenodd' undefined='1'%3E%3C/path%3E%3Cpath fill='white' d='M12 19C11.1716 19 10.5 19.6716 10.5 20.5C10.5 21.3284 11.1716 22 12 22C12.8284 22 13.5 21.3284 13.5 20.5C13.5 19.6716 12.8284 19 12 19Z' clip-rule='evenodd' fill-rule='evenodd' undefined='1'%3E%3C/path%3E%3Cpath fill='white' d='M7.75 3.14001C6.92157 3.14001 6.25 3.81159 6.25 4.64001C6.25 5.46844 6.92157 6.14001 7.75 6.14001C8.57843 6.14001 9.25 5.46844 9.25 4.64001C9.25 3.81159 8.57843 3.14001 7.75 3.14001Z' clip-rule='evenodd' fill-rule='evenodd' undefined='1'%3E%3C/path%3E%3Cpath fill='white' d='M16.25 17.86C15.4216 17.86 14.75 18.5316 14.75 19.36C14.75 20.1884 15.4216 20.86 16.25 20.86C17.0784 20.86 17.75 20.1884 17.75 19.36C17.75 18.5316 17.0784 17.86 16.25 17.86Z' clip-rule='evenodd' fill-rule='evenodd' undefined='1'%3E%3C/path%3E%3Cpath fill='white' d='M4.64001 6.25C3.81159 6.25 3.14001 6.92157 3.14001 7.75C3.14001 8.57843 3.81159 9.25 4.64001 9.25C5.46844 9.25 6.14001 8.57843 6.14001 7.75C6.14001 6.92157 5.46844 6.25 4.64001 6.25Z' clip-rule='evenodd' fill-rule='evenodd' undefined='1'%3E%3C/path%3E%3Cpath fill='white' d='M19.36 14.75C18.5316 14.75 17.86 15.4216 17.86 16.25C17.86 17.0784 18.5316 17.75 19.36 17.75C20.1884 17.75 20.86 17.0784 20.86 16.25C20.86 15.4216 20.1884 14.75 19.36 14.75Z' clip-rule='evenodd' fill-rule='evenodd' undefined='1'%3E%3C/path%3E%3Cpath fill='white' d='M3.5 10.5C2.67157 10.5 2 11.1716 2 12C2 12.8284 2.67157 13.5 3.5 13.5C4.32843 13.5 5 12.8284 5 12C5 11.1716 4.32843 10.5 3.5 10.5Z' clip-rule='evenodd' fill-rule='evenodd' undefined='1'%3E%3C/path%3E%3Cpath fill='white' d='M20.5 10.5C19.6716 10.5 19 11.1716 19 12C19 12.8284 19.6716 13.5 20.5 13.5C21.3284 13.5 22 12.8284 22 12C22 11.1716 21.3284 10.5 20.5 10.5Z' clip-rule='evenodd' fill-rule='evenodd' undefined='1'%3E%3C/path%3E%3Cpath fill='white' d='M4.64001 14.75C3.81159 14.75 3.14001 15.4216 3.14001 16.25C3.14001 17.0784 3.81159 17.75 4.64001 17.75C5.46844 17.75 6.14001 17.0784 6.14001 16.25C6.14001 15.4216 5.46844 14.75 4.64001 14.75Z' clip-rule='evenodd' fill-rule='evenodd' undefined='1'%3E%3C/path%3E%3Cpath fill='white' d='M19.36 6.25C18.5316 6.25 17.86 6.92157 17.86 7.75C17.86 8.57843 18.5316 9.25 19.36 9.25C20.1884 9.25 20.86 8.57843 20.86 7.75C20.86 6.92157 20.1884 6.25 19.36 6.25Z' clip-rule='evenodd' fill-rule='evenodd' undefined='1'%3E%3C/path%3E%3Cpath fill='white' d='M7.75 17.86C6.92157 17.86 6.25 18.5316 6.25 19.36C6.25 20.1884 6.92157 20.86 7.75 20.86C8.57843 20.86 9.25 20.1884 9.25 19.36C9.25 18.5316 8.57843 17.86 7.75 17.86Z' clip-rule='evenodd' fill-rule='evenodd' undefined='1'%3E%3C/path%3E%3Cpath fill='white' d='M16.25 3.14001C15.4216 3.14001 14.75 3.81159 14.75 4.64001C14.75 5.46844 15.4216 6.14001 16.25 6.14001C17.0784 6.14001 17.75 5.46844 17.75 4.64001C17.75 3.81159 17.0784 3.14001 16.25 3.14001Z' clip-rule='evenodd' fill-rule='evenodd' undefined='1'%3E%3C/path%3E%3C/svg%3E%0A");
    94202    display: block;
    95203}
    96204
    97 #ta-command-palette-items {
     205#ta-command-palette-items-container,
     206#wpadminbar #ta-command-palette-items-container {
     207    position: relative;
     208    background-color: #000;
     209    font-size: inherit;
     210    line-height: 1.3;
     211    display: block;
     212    margin: 0;
     213    padding: 0;
     214    width: 100%;
     215    height: 80%;
     216    max-height: 300px;
     217    color: #FFF;
     218    overflow: hidden;
     219}
     220
     221#ta-command-palette-items,
     222#ta-command-palette-submenu-container,
     223#wpadminbar #ta-command-palette-items,
     224#wpadminbar #ta-command-palette-submenu-container {
    98225    position: relative;
    99226    background-color: #000;
     
    105232    list-style-type: none;
    106233    width: 100%;
    107     height: 80%;
    108     max-height: 300px;
     234    height: 100%;
     235    max-height: 300px;
    109236    overflow-x: hidden;
    110237    overflow-y: scroll;
    111     color: #FFF;
    112238    scrollbar-width: thin;          /* "auto" or "thin" */
    113239    scrollbar-color: #444 #000;   /* scroll thumb and track */
    114240}
    115 #ta-command-palette-items::-webkit-scrollbar {
     241
     242#ta-command-palette-submenu-container,
     243#wpadminbar #ta-command-palette-submenu-container {
     244    position: absolute;
     245    top: 0;
     246    left: 100%;
     247    height: auto;
     248    min-height: 100%;
     249    transition: left 0.3s;
     250}
     251
     252#ta-command-palette-submenu-container.active,
     253#wpadminbar #ta-command-palette-submenu-container.active {
     254    left: 0;
     255}
     256
     257#ta-command-palette-items::-webkit-scrollbar,
     258#ta-command-palette-submenu-container::-webkit-scrollbar {
    116259  width: 6px;               /* width of the entire scrollbar */
    117260}
    118261
    119 #ta-command-palette-items::-webkit-scrollbar-track {
     262#ta-command-palette-items::-webkit-scrollbar-track,
     263#ta-command-palette-submenu-container::-webkit-scrollbar {
    120264  background: #000;        /* color of the tracking area */
    121265}
    122266
    123 #ta-command-palette-items::-webkit-scrollbar-thumb {
     267#ta-command-palette-items::-webkit-scrollbar-thumb,
     268#ta-command-palette-submenu-container::-webkit-scrollbar {
    124269  background-color: #444;    /* color of the scroll thumb */
    125270  border-radius: 20px;       /* roundness of the scroll thumb */
     
    127272}
    128273
    129 #ta-command-palette li {
     274#ta-command-palette li,
     275#wpadminbar #ta-command-palette li {
    130276    display: block;
    131277    margin: 0 !important;
     
    133279}
    134280
    135 #ta-command-palette a {
     281#ta-command-palette a,
     282#wpadminbar #ta-command-palette a {
    136283    display: flex;
    137284    flex-shrink: 0;
     
    182329}
    183330
     331/* Submenu items are all hidden - the markup is copied to the submenu container */
    184332#ta-command-palette .ta-submenu {
     333    display: none;
     334}
     335#ta-command-palette #ta-command-palette-submenu-container .ta-submenu {
     336    display: block;
     337}
     338
     339/* #ta-command-palette .ta-submenu {
    185340    position: absolute;
    186341    right: -100%;
     
    195350#ta-command-palette .ta-submenu.active {
    196351    right: 0;
    197 }
     352} */
    198353
    199354#ta-command-palette .ta-submenu-title {
     
    216371    width: auto;
    217372    height: auto;
     373    padding: 3px 5px 3px 5px;
    218374    position: relative;
    219375    background-color: none;
    220376    transition: none;
     377    overflow: visible;
    221378}
    222379
     
    239396    opacity: 1;
    240397    transition: none;
    241     padding: 3px 5px 3px 5px;
     398    padding: 0;
    242399    background-color: #1d2327;
    243400}
    244401
     402#wpadminbar #ta-command-palette-tab-notice {
     403    top: 3px;
     404    right: 10px;
     405}
     406#wpadminbar #ta-command-palette-tab-notice-text {
     407    display: none;
     408}
    245409#wpadminbar #ta-command-palette-input {
    246410    line-height: 1.6;
     
    254418#wpadminbar #ta-shortcut-key-placeholder {
    255419    position: absolute;
    256     top: 8px;
     420    top: 6px;
    257421    left: 12px;
     422    z-index: 100;
    258423}
    259424
     
    280445    height: auto;
    281446}
     447
     448#wpadminbar #ta-command-palette-submenu-container {
     449    background-color: #1d2327;
     450    z-index: 100000;
     451}
     452
    282453#wpadminbar #ta-command-palette-items .ta-submenu {
    283454    background-color: #1d2327;
    284455}
     456
    285457#wpadminbar #ta-command-palette-items .ta-has-child-menu.selected {
    286458    z-index: 9999999; /* Needs to be higher than #ta-command-palette-container */
     
    304476#wpadminbar #ta-command-palette-container.active #ta-command-palette-items {
    305477    padding-top: 8px;
    306     max-height: 400px;
     478    max-height: 300px;
    307479    opacity: 1;
    308480}
Note: See TracChangeset for help on using the changeset viewer.