demystify 0.2.0

A constraint solving tool for explaining puzzles
Documentation
function applyHighlight(element) {
  const classes = element.classList;
  for (let i = 0; i < classes.length; i++) {
    const className = classes[i];
    if (className.startsWith("highlight_")) {
      console.log(className)
      const highlightedElements = document.getElementsByClassName(className);
      for (let j = 0; j < highlightedElements.length; j++) {
        highlightedElements[j].classList.add("selected");
      }
    }
  }
}

function removeHighlight(element) {
  const classes = element.classList;
  for (let i = 0; i < classes.length; i++) {
    const className = classes[i];
    if (className.startsWith("highlight_")) {
      const highlightedElements = document.getElementsByClassName(className);
      for (let j = 0; j < highlightedElements.length; j++) {
        highlightedElements[j].classList.remove("selected");
      }
    }
  }
}

function applyHighlightFunctions() {
  const elements = document.getElementsByClassName("js_highlighter");
  for (let i = 0; i < elements.length; i++) {
    const element = elements[i];
    element.addEventListener("mouseover", () => {
      applyHighlight(element);
    });
    element.addEventListener("mouseleave", () => {
      removeHighlight(element);
    });
  }
}

function applyConstraintPreview(element) {
  const cells = element.dataset.cells ? element.dataset.cells.split(" ") : [];
  cells.forEach(id => {
    const el = document.getElementById(id);
    if (el) el.classList.add("con-preview");
  });
}

function removeConstraintPreview(element) {
  const cells = element.dataset.cells ? element.dataset.cells.split(" ") : [];
  cells.forEach(id => {
    const el = document.getElementById(id);
    if (el) el.classList.remove("con-preview");
  });
}

function applyConstraintPreviewFunctions() {
  document.querySelectorAll(".js_con_preview").forEach(el => {
    el.addEventListener("mouseover", () => applyConstraintPreview(el));
    el.addEventListener("mouseleave", () => removeConstraintPreview(el));
  });
}

function doJavascript() {
  applyHighlightFunctions();
  applyConstraintPreviewFunctions();

  document.addEventListener("htmx:beforeRequest", function () {
    document.querySelectorAll("button").forEach((btn) => {
      if (!btn.disabled) {
        btn.disabled = true;
        btn.dataset.htmxDisabled = "true"; // Mark this button
      }
    });
    document.body.style.cursor = "wait";
  });

  document.addEventListener("htmx:afterRequest", function () {
    document.querySelectorAll('[data-htmx-disabled="true"]').forEach((btn) => {
      btn.disabled = false;
      delete btn.dataset.htmxDisabled; // Clean up
    });
    document.body.style.cursor = "default";
  });
}