(function () {
  var preview = document.querySelector("[data-source-url][data-file-name][data-content-type]");
  if (!preview) {
    return;
  }

  var SMALL_TEXT_BYTES = 50 * 1024;
  var LARGE_PREVIEW_BYTES = 500 * 1024;

  var state = {
    fileName: preview.dataset.fileName || "",
    contentType: (preview.dataset.contentType || "").toLowerCase(),
    previewKind: preview.dataset.previewKind || "",
    sizeBytes: Number(preview.dataset.sizeBytes || 0),
    sizeLabel: preview.dataset.fileSize || "",
    sourceURL: preview.dataset.sourceUrl || "",
    downloadURL: preview.dataset.downloadUrl || "",
    iconURL: preview.dataset.iconUrl || "",
    sceneURL: preview.dataset.sceneUrl || "",
    archiveURL: preview.dataset.archiveUrl || "",
    activeMode: "",
    defaultMode: "default",
    pendingMode: "",
    textSource: "",
    textLoaded: false,
    rawLoaded: false,
    prismLoaded: false,
    renderLoaded: false,
    sceneLoaded: false,
    archiveLoaded: false,
    archiveUIRendered: false,
    archiveData: null,
    archiveText: "",
    renderFullscreenFallback: false,
    confirmedLargeModes: {},
    tabs: []
  };

  var els = {
    tabs: preview.querySelector("[data-preview-tabs]"),
    modeLabel: preview.querySelector("[data-preview-mode-label]"),
    defaultPane: preview.querySelector("[data-default-preview]"),
    imagePane: preview.querySelector("[data-image-preview]"),
    videoPane: preview.querySelector("[data-video-preview]"),
    videoScenesPane: preview.querySelector("[data-video-scenes-preview]"),
    browserAudioPane: preview.querySelector("[data-browser-audio-preview]"),
    rawPane: preview.querySelector("[data-raw-preview]"),
    rawOutput: preview.querySelector("[data-raw-output]"),
    codePane: preview.querySelector("[data-code-preview]"),
    codeOutput: preview.querySelector("[data-code-output]"),
    archiveBrowserPane: preview.querySelector("[data-archive-browser-preview]"),
    archivePane: preview.querySelector("[data-archive-preview]"),
    archiveOutput: preview.querySelector("[data-archive-output]"),
    renderPane: preview.querySelector("[data-render-preview]"),
    fullscreenButton: preview.querySelector("[data-render-fullscreen]"),
    gatePane: preview.querySelector("[data-large-preview-gate]"),
    gateConfirm: preview.querySelector("[data-large-preview-confirm]"),
    gateCancel: preview.querySelector("[data-large-preview-cancel]"),
    placeholder: preview.querySelector("[data-preview-placeholder]")
  };

  var fileType = detectFileType();
  state.tabs = buildTabs(fileType);
  state.defaultMode = chooseDefaultMode(fileType, state.tabs);

  bindLargeGate();
  bindThemeChanges();
  bindRenderFullscreen();
  configureMediaSession();
  renderTabs();
  selectMode(state.defaultMode);

  function detectFileType() {
    var extension = extensionFor(state.fileName);
    var baseType = state.contentType.split(";")[0].trim();
    var language = languageFor(extension, baseType);
    var isImage = state.previewKind === "image" || baseType.indexOf("image/") === 0 && baseType !== "image/svg+xml";
    var isVideo = state.previewKind === "video" || baseType.indexOf("video/") === 0;
    var isAudio = state.previewKind === "audio" || baseType.indexOf("audio/") === 0;
    var isArchive = Boolean(state.archiveURL) && isArchiveFile(extension, baseType);

    return {
      extension: extension,
      baseType: baseType,
      language: language,
      isTextLike: Boolean(language),
      isHTML: language === "html",
      isMarkdown: language === "markdown",
      isImage: isImage,
      isVideo: isVideo,
      isAudio: isAudio,
      isArchive: isArchive,
      isMobile: window.matchMedia && window.matchMedia("(max-width: 720px), (pointer: coarse)").matches
    };
  }

  function buildTabs(type) {
    var tabs = [{ mode: "default", label: "Default" }];

    if (type.isImage) {
      tabs.push({ mode: "image", label: "Image Preview" });
      return tabs;
    }

    if (type.isVideo) {
      tabs.push({ mode: "video", label: "Video Preview" });
      if (state.sceneURL && els.videoScenesPane) {
        tabs.push({ mode: "scenes", label: "Scenes Preview" });
      }
      return tabs;
    }

    if (type.isAudio) {
      tabs.push({ mode: "browser-audio", label: "Browser Preview" });
      return tabs;
    }

    if (type.isArchive) {
      tabs.push({ mode: "archive-ui", label: "Archive Preview" });
      tabs.push({ mode: "archive", label: "Text Tree" });
      return tabs;
    }

    if (type.isTextLike) {
      if (type.isHTML || type.isMarkdown) {
        tabs.push({ mode: "render", label: "Render Preview" });
      }
      tabs.push({ mode: "raw", label: "Raw Preview" });
      tabs.push({ mode: "code", label: "Code Preview" });
    }

    return tabs;
  }

  function chooseDefaultMode(type, tabs) {
    if (type.isImage) {
      return "image";
    }
    if (type.isVideo) {
      return "video";
    }
    if (type.isArchive) {
      return "archive-ui";
    }
    if (state.sizeBytes > LARGE_PREVIEW_BYTES) {
      if (type.isAudio && hasMode(tabs, "browser-audio")) {
        return "browser-audio";
      }
      return "default";
    }
    if (type.isAudio) {
      return "browser-audio";
    }
    if (type.isTextLike && state.sizeBytes > SMALL_TEXT_BYTES) {
      return "raw";
    }
    if (type.isMarkdown) {
      return "render";
    }
    if (type.isTextLike) {
      return "code";
    }
    return "default";
  }

  function renderTabs() {
    if (!els.tabs) {
      return;
    }
    els.tabs.innerHTML = "";
    state.tabs.forEach(function (tab) {
      var button = document.createElement("button");
      button.className = "preview-tab";
      button.type = "button";
      button.dataset.previewTab = tab.mode;
      button.textContent = tab.label;
      button.addEventListener("click", function () {
        selectMode(tab.mode);
      });
      els.tabs.appendChild(button);
    });
  }

  function selectMode(mode) {
    if (!hasMode(state.tabs, mode)) {
      mode = "default";
    }

    if (mode !== "render") {
      exitRenderFullscreen();
    }

    if (requiresLargeConfirmation(mode)) {
      showLargeGate(mode);
      return;
    }

    state.activeMode = mode;
    updateTabs(mode);
    updateRenderFullscreenButton();
    hideAllPanes();
    setModeLabel(labelForMode(mode));

    if (mode === "default") {
      show(els.defaultPane);
    } else if (mode === "image") {
      show(els.imagePane);
    } else if (mode === "video") {
      show(els.videoPane);
    } else if (mode === "scenes") {
      show(els.videoScenesPane);
      ensureScenesPreview();
    } else if (mode === "browser-audio") {
      show(els.browserAudioPane);
    } else if (mode === "raw") {
      show(els.rawPane);
      ensureRawPreview();
    } else if (mode === "code") {
      show(els.codePane);
      ensurePrismPreview();
    } else if (mode === "archive-ui") {
      show(els.archiveBrowserPane);
      ensureArchiveBrowserPreview();
    } else if (mode === "archive") {
      show(els.archivePane);
      ensureArchivePreview();
    } else if (mode === "render") {
      show(els.renderPane);
      if (fileType.isMarkdown) {
        ensureMarkdownRenderPreview();
      } else {
        ensureHTMLRenderPreview();
      }
    }
  }

  function requiresLargeConfirmation(mode) {
    if (state.sizeBytes <= LARGE_PREVIEW_BYTES || state.confirmedLargeModes[mode]) {
      return false;
    }
    return mode === "raw" || mode === "code" || mode === "render";
  }

  function showLargeGate(mode) {
    state.pendingMode = mode;
    updateTabs(state.activeMode || state.defaultMode);
    updateRenderFullscreenButton(false);
    hideAllPanes();
    show(els.gatePane);
    setModeLabel("Large preview");
  }

  function bindLargeGate() {
    if (els.gateConfirm) {
      els.gateConfirm.addEventListener("click", function () {
        if (!state.pendingMode) {
          return;
        }
        state.confirmedLargeModes[state.pendingMode] = true;
        selectMode(state.pendingMode);
      });
    }
    if (els.gateCancel) {
      els.gateCancel.addEventListener("click", function () {
        state.pendingMode = "";
        selectMode(state.activeMode || state.defaultMode || "default");
      });
    }
  }

  function bindThemeChanges() {
    var themeSelect = document.querySelector("[data-theme-select]");
    if (!themeSelect) {
      return;
    }
    themeSelect.addEventListener("change", function () {
      window.setTimeout(function () {
        if (!fileType.isMarkdown || !state.renderLoaded) {
          return;
        }
        state.renderLoaded = false;
        if (state.activeMode === "render") {
          ensureMarkdownRenderPreview();
        }
      }, 0);
    });
  }

  function bindRenderFullscreen() {
    if (!els.fullscreenButton) {
      return;
    }

    els.fullscreenButton.addEventListener("click", function () {
      if (isRenderFullscreen()) {
        exitRenderFullscreen();
        return;
      }
      enterRenderFullscreen();
    });

    document.addEventListener("fullscreenchange", updateRenderFullscreenButton);
  }

  function configureMediaSession() {
    if (!("mediaSession" in navigator) || typeof window.MediaMetadata !== "function") {
      return;
    }
    if (!fileType.isAudio && !fileType.isVideo) {
      return;
    }
    var artworkURL = "";
    if (fileType.isVideo && els.videoPane) {
      artworkURL = els.videoPane.getAttribute("poster") || state.iconURL || "";
    } else {
      artworkURL = state.iconURL || "";
    }
    var metadata = {
      title: state.fileName || "Warpbox media",
      artist: "Warpbox",
      album: state.sizeLabel || state.contentType || ""
    };
    if (artworkURL) {
      metadata.artwork = [
        { src: window.Warpbox.absoluteURL(artworkURL), sizes: "512x512", type: "image/png" }
      ];
    }
    navigator.mediaSession.metadata = new MediaMetadata(metadata);
  }

  function ensureTextLoaded() {
    if (state.textLoaded) {
      return Promise.resolve(state.textSource);
    }

    showLoading("Loading preview...");
    return fetch(state.sourceURL, { credentials: "same-origin" })
      .then(function (response) {
        if (!response.ok) {
          throw new Error("Preview failed");
        }
        return response.text();
      })
      .then(function (source) {
        state.textSource = source;
        state.textLoaded = true;
        hide(els.placeholder);
        return source;
      })
      .catch(function (error) {
        showError("Preview unavailable");
        throw error;
      });
  }

  function ensureRawPreview() {
    if (state.rawLoaded) {
      return;
    }

    ensureTextLoaded().then(function (source) {
      els.rawOutput.textContent = source;
      state.rawLoaded = true;
      if (state.activeMode === "raw") {
        hide(els.placeholder);
        show(els.rawPane);
      }
    });
  }

  function ensurePrismPreview() {
    if (state.prismLoaded) {
      return;
    }

    showLoading("Loading syntax preview...");
    Promise.all([ensureTextLoaded(), loadPrism()])
      .then(function (results) {
        var source = results[0];
        var language = fileType.language;
        if (language === "json") {
          source = formatJSON(source);
        }
        els.codeOutput.className = "language-" + language;
        els.codeOutput.textContent = source;
        if (window.Prism) {
          window.Prism.highlightElement(els.codeOutput);
        }
        state.prismLoaded = true;
        if (state.activeMode === "code") {
          hide(els.placeholder);
          show(els.codePane);
        }
      })
      .catch(function () {
        showError("Syntax preview unavailable");
      });
  }

  function ensureHTMLRenderPreview() {
    if (state.renderLoaded) {
      return;
    }

    showLoading("Rendering preview...");
    ensureTextLoaded()
      .then(function (source) {
        els.renderPane.srcdoc = withBaseElement(source);
        state.renderLoaded = true;
        if (state.activeMode === "render") {
          hide(els.placeholder);
          show(els.renderPane);
        }
      })
      .catch(function () {
        showError("Render preview unavailable");
      });
  }

  function ensureMarkdownRenderPreview() {
    if (state.renderLoaded) {
      return;
    }

    showLoading("Rendering Markdown...");
    Promise.all([ensureTextLoaded(), loadMarkdownLibs()])
      .then(function (results) {
        var markdown = results[0];
        var html = parseMarkdown(markdown);
        var clean = window.DOMPurify.sanitize(html);
        els.renderPane.srcdoc = markdownDocument(clean);
        state.renderLoaded = true;
        if (state.activeMode === "render") {
          hide(els.placeholder);
          show(els.renderPane);
        }
      })
      .catch(function () {
        showError("Markdown preview unavailable");
      });
  }

  function showLoading(message) {
    if (!els.placeholder) {
      return;
    }
    var text = els.placeholder.querySelector("p");
    if (text) {
      text.textContent = message;
    }
    show(els.placeholder);
  }

  function showError(message) {
    hideAllPanes();
    var text = els.placeholder && els.placeholder.querySelector("p");
    if (text) {
      text.textContent = message;
    }
    show(els.placeholder);
  }

  function hideAllPanes() {
    hide(els.defaultPane);
    hide(els.imagePane);
    hide(els.videoPane);
    hide(els.videoScenesPane);
    hide(els.browserAudioPane);
    hide(els.rawPane);
    hide(els.codePane);
    hide(els.archiveBrowserPane);
    hide(els.archivePane);
    hide(els.renderPane);
    hide(els.gatePane);
    hide(els.placeholder);
  }

  function enterRenderFullscreen() {
    if (state.activeMode !== "render") {
      return;
    }

    if (preview.requestFullscreen) {
      var request = preview.requestFullscreen();
      if (request && typeof request.catch === "function") {
        request.catch(function () {
          state.renderFullscreenFallback = true;
          preview.classList.add("is-render-fullscreen");
          updateRenderFullscreenButton();
        });
      }
      return;
    }

    state.renderFullscreenFallback = true;
    preview.classList.add("is-render-fullscreen");
    updateRenderFullscreenButton();
  }

  function exitRenderFullscreen() {
    if (document.fullscreenElement === preview && document.exitFullscreen) {
      var exit = document.exitFullscreen();
      if (exit && typeof exit.catch === "function") {
        exit.catch(function () {});
      }
    }
    state.renderFullscreenFallback = false;
    preview.classList.remove("is-render-fullscreen");
    updateRenderFullscreenButton();
  }

  function isRenderFullscreen() {
    return document.fullscreenElement === preview || state.renderFullscreenFallback;
  }

  function updateRenderFullscreenButton(forceVisible) {
    if (!els.fullscreenButton) {
      return;
    }

    var visible = typeof forceVisible === "boolean" ? forceVisible : state.activeMode === "render";
    els.fullscreenButton.hidden = !visible;
    els.fullscreenButton.textContent = isRenderFullscreen() ? "Exit Full Screen" : "Full Screen";
    els.fullscreenButton.setAttribute("aria-pressed", isRenderFullscreen() ? "true" : "false");
  }

  function updateTabs(mode) {
    if (!els.tabs) {
      return;
    }
    Array.prototype.forEach.call(els.tabs.querySelectorAll("[data-preview-tab]"), function (button) {
      button.classList.toggle("is-active", button.dataset.previewTab === mode);
    });
  }

  function show(element) {
    if (element) {
      element.hidden = false;
    }
  }

  function hide(element) {
    if (element) {
      element.hidden = true;
    }
  }

  function setModeLabel(label) {
    if (els.modeLabel) {
      els.modeLabel.textContent = label;
    }
  }

  function hasMode(tabs, mode) {
    return tabs.some(function (tab) {
      return tab.mode === mode;
    });
  }

  function labelForMode(mode) {
    var labels = {
      "default": "Default",
      "image": "Image preview",
      "video": "Video preview",
      "scenes": "Scenes preview",
      "browser-audio": "Browser preview",
      "raw": "Raw preview",
      "code": "Code preview",
      "archive-ui": "Archive preview",
      "archive": "Archive preview",
      "render": "Render preview"
    };
    return labels[mode] || "Preview";
  }

  function ensureScenesPreview() {
    if (state.sceneLoaded || !els.videoScenesPane) {
      return;
    }
    var src = els.videoScenesPane.dataset.sceneSrc || state.sceneURL;
    if (!src) {
      return;
    }
    els.videoScenesPane.src = src;
    state.sceneLoaded = true;
  }

  function ensureArchivePreview() {
    if (state.archiveLoaded || !els.archiveOutput || !state.archiveURL) {
      return;
    }
    ensureArchiveData()
      .then(function () {
        var text = state.archiveText || archiveDataToText(state.archiveData);
        els.archiveOutput.textContent = text;
        state.archiveLoaded = true;
        hide(els.placeholder);
        show(els.archivePane);
      })
      .catch(function () {
        showError("Archive preview could not be loaded.");
      });
  }

  function ensureArchiveBrowserPreview() {
    if (state.archiveUIRendered || !els.archiveBrowserPane || !state.archiveURL) {
      return;
    }
    ensureArchiveData()
      .then(function () {
        renderArchiveBrowser(state.archiveData);
        state.archiveUIRendered = true;
        hide(els.placeholder);
        show(els.archiveBrowserPane);
      })
      .catch(function () {
        showError("Archive preview could not be loaded.");
      });
  }

  function ensureArchiveData() {
    if (state.archiveData || state.archiveText) {
      return Promise.resolve();
    }
    showLoading("Loading archive contents...");
    return fetch(state.archiveURL, { credentials: "same-origin" })
      .then(function (response) {
        if (!response.ok) {
          throw new Error("Archive preview could not be loaded.");
        }
        return response.text();
      })
      .then(function (text) {
        try {
          state.archiveData = JSON.parse(text);
        } catch (error) {
          state.archiveText = text;
        }
      });
  }

  function renderArchiveBrowser(data) {
    if (!els.archiveBrowserPane) {
      return;
    }
    els.archiveBrowserPane.innerHTML = "";
    if (!data || !data.root) {
      var fallback = document.createElement("pre");
      fallback.className = "archive-browser-legacy";
      fallback.textContent = state.archiveText || "Archive preview is unavailable.";
      els.archiveBrowserPane.appendChild(fallback);
      return;
    }

    var header = document.createElement("div");
    header.className = "archive-browser-header";
    header.innerHTML = "<strong></strong><span></span>";
    header.querySelector("strong").textContent = data.name || state.fileName || "Archive";
    header.querySelector("span").textContent = [
      data.type || "Archive",
      formatArchiveCount(data.fileCount, "file"),
      formatArchiveCount(data.folderCount, "folder"),
      formatBytes(data.uncompressedSize || 0)
    ].filter(Boolean).join(" · ");
    els.archiveBrowserPane.appendChild(header);

    var tree = document.createElement("div");
    tree.className = "archive-tree";
    var items = data.root.items || [];
    if (items.length === 0) {
      var emptyTree = document.createElement("p");
      emptyTree.className = "archive-browser-empty";
      emptyTree.textContent = "This archive is empty.";
      tree.appendChild(emptyTree);
    } else {
      items.forEach(function (item) {
        tree.appendChild(renderArchiveNode(item, 0));
      });
    }
    els.archiveBrowserPane.appendChild(tree);
  }

  function renderArchiveNode(node, depth) {
    var row = document.createElement(node.dir ? "details" : "div");
    row.className = node.dir ? "archive-node archive-folder" : "archive-node archive-file";
    if (node.dir && depth < 1) {
      row.open = true;
    }

    var summary = document.createElement(node.dir ? "summary" : "div");
    summary.className = "archive-node-row";
    summary.style.paddingLeft = (0.45 + depth * 1.15).toFixed(2) + "rem";

    if (node.dir) {
      summary.appendChild(createArchiveChevron());
    } else {
      var spacer = document.createElement("span");
      spacer.className = "archive-chevron-spacer";
      summary.appendChild(spacer);
    }

    summary.appendChild(createArchiveIcon(node.icon || (node.dir ? "folder" : "file")));

    var name = document.createElement("span");
    name.className = "archive-node-name";
    name.textContent = node.name + (node.dir ? "/" : "");
    summary.appendChild(name);

    if (!node.dir) {
      var size = document.createElement("span");
      size.className = "archive-node-size";
      size.textContent = formatBytes(node.size || 0);
      summary.appendChild(size);
    }

    row.appendChild(summary);
    if (node.dir) {
      (node.items || []).forEach(function (child) {
        row.appendChild(renderArchiveNode(child, depth + 1));
      });
    }
    return row;
  }

  function createArchiveChevron() {
    var chevron = document.createElement("span");
    chevron.className = "archive-chevron";
    chevron.setAttribute("aria-hidden", "true");
    chevron.innerHTML = '<svg viewBox="0 0 24 24" focusable="false"><path d="m9 6 6 6-6 6"/></svg>';
    return chevron;
  }

  function createArchiveIcon(icon) {
    var element = document.createElement("span");
    element.className = "archive-file-icon archive-file-icon-" + icon;
    element.setAttribute("aria-hidden", "true");
    element.innerHTML = '<span class="archive-svg-icon">' + archiveIconSVG(icon) + '</span>';
    var retroURL = archiveRetroIconURL(icon);
    if (retroURL) {
      var retro = document.createElement("img");
      retro.className = "archive-retro-icon";
      retro.src = retroURL;
      retro.alt = "";
      retro.decoding = "async";
      retro.loading = "lazy";
      element.appendChild(retro);
    }
    return element;
  }

  function archiveDataToText(data) {
    if (!data || !data.root) {
      return state.archiveText || "";
    }
    var lines = [
      "Archive preview",
      "Name: " + (data.name || state.fileName || "Archive"),
      "Type: " + (data.type || "Archive"),
      "Entries: " + (data.fileCount || 0) + " files, " + (data.folderCount || 0) + " folders",
      "Uncompressed size: " + formatBytes(data.uncompressedSize || 0),
      "",
      "."
    ];
    appendArchiveTextLines(lines, data.root.items || [], "");
    if (!(data.root.items || []).length) {
      lines.push("(empty archive)");
    }
    return lines.join("\n");
  }

  function appendArchiveTextLines(lines, items, prefix) {
    items.forEach(function (item, index) {
      var last = index === items.length - 1;
      var branch = last ? "`-- " : "|-- ";
      var nextPrefix = prefix + (last ? "    " : "|   ");
      var label = item.dir ? "[DIR] " + item.name + "/" : "[" + (item.icon || "file").toUpperCase() + "] " + item.name + " (" + formatBytes(item.size || 0) + ")";
      lines.push(prefix + branch + label);
      if (item.dir) {
        appendArchiveTextLines(lines, item.items || [], nextPrefix);
      }
    });
  }

  function archiveIconSVG(icon) {
    var icons = {
      folder: '<svg viewBox="0 0 24 24" focusable="false"><path d="M3 6.75A2.75 2.75 0 0 1 5.75 4h4.1l2 2.2h6.4A2.75 2.75 0 0 1 21 8.95v8.3A2.75 2.75 0 0 1 18.25 20H5.75A2.75 2.75 0 0 1 3 17.25Z"/></svg>',
      img: '<svg viewBox="0 0 24 24" focusable="false"><rect x="4" y="5" width="16" height="14" rx="2"/><path d="m7 16 3.2-3.2 2.6 2.6 2.2-2.2L19 17"/><circle cx="9" cy="9" r="1.4"/></svg>',
      vid: '<svg viewBox="0 0 24 24" focusable="false"><rect x="4" y="6" width="12" height="12" rx="2"/><path d="m16 10 4-2.5v9L16 14"/></svg>',
      aud: '<svg viewBox="0 0 24 24" focusable="false"><path d="M9 18V6l10-2v12"/><circle cx="7" cy="18" r="3"/><circle cx="17" cy="16" r="3"/></svg>',
      txt: '<svg viewBox="0 0 24 24" focusable="false"><path d="M7 3h7l4 4v14H7Z"/><path d="M14 3v5h5M9 12h6M9 15h6M9 18h4"/></svg>',
      code: '<svg viewBox="0 0 24 24" focusable="false"><path d="m9 8-4 4 4 4M15 8l4 4-4 4M13 5l-2 14"/></svg>',
      arc: '<svg viewBox="0 0 24 24" focusable="false"><path d="M7 3h7l4 4v14H7Z"/><path d="M14 3v5h5M10 6h2M10 9h2M10 12h2M10 15h2M10 18h2"/></svg>',
      file: '<svg viewBox="0 0 24 24" focusable="false"><path d="M7 3h7l4 4v14H7Z"/><path d="M14 3v5h5"/></svg>'
    };
    return icons[icon] || icons.file;
  }

  function archiveRetroIconURL(icon) {
    var base = "/static/file-icons/retro/";
    var icons = {
      folder: "directory_open_file_mydocs-4.png",
      img: "shimgvw.dll_14_1-2.png",
      vid: "wmploc.dll_14_504-2.png",
      aud: "wmploc.dll_14_610-2.png",
      txt: "shell32.dll_14_151-2.png",
      code: "mshtml.dll_14_2660-2.png",
      arc: "zipfldr.dll_14_101-2.png",
      file: "shell32.dll_14_152-2.png"
    };
    return base + (icons[icon] || icons.file);
  }

  function formatArchiveCount(value, label) {
    value = Number(value || 0);
    return value + " " + label + (value === 1 ? "" : "s");
  }

  function formatBytes(value) {
    value = Number(value || 0);
    if (value < 1024) {
      return value + " B";
    }
    var units = ["KiB", "MiB", "GiB", "TiB"];
    var size = value / 1024;
    for (var i = 0; i < units.length; i++) {
      if (size < 1024 || i === units.length - 1) {
        return size.toFixed(1) + " " + units[i];
      }
      size /= 1024;
    }
    return value + " B";
  }

  function loadPrism() {
    if (window.Prism) {
      return Promise.resolve();
    }

    window.Prism = window.Prism || {};
    window.Prism.manual = true;
    return Promise.all([
      loadStyle("/static/lib/prismjs/prism.css"),
      loadScript("/static/lib/prismjs/prism.js")
    ]);
  }

  function loadMarkdownLibs() {
    if (window.marked && window.DOMPurify) {
      return Promise.resolve();
    }

    return Promise.all([
      loadScript("/static/lib/markdown/marked.umd.js"),
      loadScript("/static/lib/markdown/purify.min.js")
    ]);
  }

  function loadScript(src) {
    return new Promise(function (resolve, reject) {
      var existing = document.querySelector('script[src="' + src + '"]');
      if (existing) {
        if (existing.dataset.loaded === "true") {
          resolve();
          return;
        }
        existing.addEventListener("load", resolve, { once: true });
        existing.addEventListener("error", reject, { once: true });
        return;
      }

      var script = document.createElement("script");
      script.async = true;
      script.src = src;
      script.addEventListener("load", function () {
        script.dataset.loaded = "true";
        resolve();
      }, { once: true });
      script.addEventListener("error", reject, { once: true });
      document.head.appendChild(script);
    });
  }

  function loadStyle(href) {
    if (document.querySelector('link[href="' + href + '"]')) {
      return Promise.resolve();
    }
    return new Promise(function (resolve, reject) {
      var link = document.createElement("link");
      link.rel = "stylesheet";
      link.href = href;
      link.addEventListener("load", resolve, { once: true });
      link.addEventListener("error", reject, { once: true });
      document.head.appendChild(link);
    });
  }

  function parseMarkdown(source) {
    if (window.marked && typeof window.marked.parse === "function") {
      return window.marked.parse(source);
    }
    if (window.marked && window.marked.marked && typeof window.marked.marked.parse === "function") {
      return window.marked.marked.parse(source);
    }
    throw new Error("Marked unavailable");
  }

  function markdownDocument(body) {
    var theme = currentTheme();
    var base = '<base href="' + escapeAttribute(new URL(state.sourceURL, window.location.href).href) + '">';
    return '<!doctype html><html data-theme="' + escapeAttribute(theme) + '"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">' +
      base +
      '<link rel="stylesheet" href="/static/css/80-markdown-preview.css">' +
      '<style>' + markdownThemeStyle(theme) + '</style>' +
      '</head><body><main>' + body + '</main></body></html>';
  }

  function markdownThemeStyle(theme) {
    var themes = {
      revamp: ["dark", "#0b0b16", "#f5f3ff", "#aaa4d6", "#17142d", "#211b3e", "rgba(168,150,255,0.24)", "#67e8f9", "#a78bfa", "#1b1724", "#0f111a", "#f8fafc", "rgba(248,250,252,0.16)", "rgba(0,0,0,0.28)", "Inter,system-ui,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans serif", "Consolas,Monaco,\"Andale Mono\",\"Ubuntu Mono\",monospace"],
      classic: ["dark", "#09090b", "#fafafa", "#a1a1aa", "#18181b", "#27272a", "rgba(255,255,255,0.13)", "#e4e4e7", "#d4d4d8", "#111113", "#09090b", "#fafafa", "rgba(250,250,250,0.15)", "rgba(0,0,0,0.3)", "Inter,system-ui,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans serif", "Consolas,Monaco,\"Andale Mono\",\"Ubuntu Mono\",monospace"],
      retro: ["light", "#c0c0c0", "#000000", "#404040", "#ffffff", "#dfdfdf", "#000000", "#000078", "#000078", "#ffffff", "#000000", "#f5f5f5", "#808080", "transparent", "\"PixeloidSans\",\"PixelOperator\",\"Microsoft Sans Serif\",Tahoma,sans serif", "\"PixelOperatorMono\",Consolas,monospace"],
      gruvbox: ["dark", "#1d2021", "#ebdbb2", "#bdae93", "#282828", "#32302f", "rgba(235,219,178,0.2)", "#fabd2f", "#d79921", "#1b1d1e", "#161819", "#fbf1c7", "rgba(251,241,199,0.18)", "rgba(0,0,0,0.26)", "Inter,system-ui,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans serif", "Consolas,Monaco,\"Andale Mono\",\"Ubuntu Mono\",monospace"],
      cyberpunk: ["dark", "#08070d", "#fff36f", "#9bfaff", "#16131f", "#251d34", "rgba(255,242,0,0.34)", "#00f0ff", "#ff2a6d", "#100d18", "#07060b", "#f8fafc", "rgba(0,240,255,0.26)", "rgba(255,42,109,0.14)", "Inter,system-ui,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans serif", "Consolas,Monaco,\"Andale Mono\",\"Ubuntu Mono\",monospace"]
    };
    var t = themes[theme] || themes.revamp;
    var vars = "color-scheme:" + t[0] + ";--md-bg:" + t[1] + ";--md-fg:" + t[2] + ";--md-muted:" + t[3] + ";--md-panel:" + t[4] + ";--md-panel-2:" + t[5] + ";--md-border:" + t[6] + ";--md-link:" + t[7] + ";--md-accent:" + t[8] + ";--md-code-bg:" + t[9] + ";--md-block-code-bg:" + t[10] + ";--md-block-code-fg:" + t[11] + ";--md-block-code-border:" + t[12] + ";--md-shadow:" + t[13] + ";--md-font:" + t[14] + ";--md-mono:" + t[15] + ";";
    return ":root{" + vars + "}*{box-sizing:border-box}html,body{min-height:100%;margin:0;background:var(--md-bg);color:var(--md-fg);font-family:var(--md-font)}body{padding:clamp(1rem,4vw,2.25rem);font-size:16px;line-height:1.65}main{max-width:54rem;margin:0 auto;padding:clamp(1rem,3vw,2rem);border:1px solid var(--md-border);border-radius:10px;background:var(--md-panel);box-shadow:0 20px 60px var(--md-shadow)}a{color:var(--md-link)}h1,h2,h3,h4,h5,h6{color:var(--md-fg);line-height:1.2}code,kbd,pre{font-family:var(--md-mono)}pre{overflow:auto;padding:1rem;border:1px solid var(--md-block-code-border)!important;background:var(--md-block-code-bg)!important;color:var(--md-block-code-fg)!important}code{background:var(--md-code-bg);border-radius:4px;padding:.12rem .3rem}pre code,pre>code,pre code[class*=\"language-\"]{padding:0!important;background:transparent!important;color:inherit!important;border:0!important}blockquote{margin:1rem 0;padding:.2rem 1rem;border-left:3px solid var(--md-accent);color:var(--md-muted);background:var(--md-panel-2)}table{width:100%;border-collapse:collapse;display:block;overflow:auto}th,td{border:1px solid var(--md-border);padding:.5rem .7rem}hr{border:0;border-top:1px solid var(--md-border)}img,video{max-width:100%;height:auto}";
  }

  function currentTheme() {
    var theme = document.documentElement.dataset.theme || "revamp";
    return /^(revamp|classic|retro|gruvbox|cyberpunk)$/.test(theme) ? theme : "revamp";
  }

  function withBaseElement(source) {
    var base = '<base href="' + escapeAttribute(new URL(state.sourceURL, window.location.href).href) + '">';
    if (/<head[\s>]/i.test(source)) {
      return source.replace(/<head([^>]*)>/i, "<head$1>" + base);
    }
    return base + source;
  }

  function escapeAttribute(value) {
    return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;");
  }

  function formatJSON(source) {
    try {
      return JSON.stringify(JSON.parse(source), null, 2);
    } catch (error) {
      return source;
    }
  }

  function extensionFor(name) {
    var parts = name.toLowerCase().split(".");
    return parts.length > 1 ? parts.pop() : "";
  }

  function isArchiveFile(extension, baseType) {
    var archiveExtensions = {
      "apk": true,
      "docx": true,
      "ear": true,
      "epub": true,
      "jar": true,
      "pptx": true,
      "war": true,
      "xlsx": true,
      "zip": true
    };
    var archiveTypes = {
      "application/epub+zip": true,
      "application/java-archive": true,
      "application/vnd.android.package-archive": true,
      "application/x-zip-compressed": true,
      "application/zip": true
    };
    return Boolean(archiveExtensions[extension] || archiveTypes[baseType]);
  }

  function languageFor(extension, baseType) {
    var extensionMap = {
      "c": "c",
      "cc": "cpp",
      "conf": "nginx",
      "cpp": "cpp",
      "cs": "csharp",
      "css": "css",
      "csv": "csv",
      "diff": "diff",
      "dockerfile": "docker",
      "go": "go",
      "h": "c",
      "hpp": "cpp",
      "htm": "html",
      "html": "html",
      "ini": "ini",
      "java": "java",
      "js": "javascript",
      "json": "json",
      "jsx": "jsx",
      "kt": "kotlin",
      "log": "log",
      "lua": "lua",
      "md": "markdown",
      "mdown": "markdown",
      "markdown": "markdown",
      "php": "php",
      "pl": "perl",
      "properties": "properties",
      "py": "python",
      "rb": "ruby",
      "rs": "rust",
      "sh": "bash",
      "sql": "sql",
      "swift": "swift",
      "toml": "toml",
      "ts": "typescript",
      "tsx": "tsx",
      "txt": "text",
      "xml": "xml",
      "yaml": "yaml",
      "yml": "yaml",
      "zig": "zig"
    };
    var typeMap = {
      "application/javascript": "javascript",
      "application/json": "json",
      "application/ld+json": "json",
      "application/markdown": "markdown",
      "application/xml": "xml",
      "application/x-httpd-php": "php",
      "application/x-sh": "bash",
      "image/svg+xml": "xml",
      "text/css": "css",
      "text/csv": "csv",
      "text/html": "html",
      "text/javascript": "javascript",
      "text/markdown": "markdown",
      "text/plain": "text",
      "text/x-go": "go",
      "text/xml": "xml"
    };

    if (extensionMap[extension]) {
      return extensionMap[extension];
    }
    if (typeMap[baseType]) {
      return typeMap[baseType];
    }
    if (baseType.indexOf("+json") !== -1) {
      return "json";
    }
    if (baseType.indexOf("+xml") !== -1) {
      return "xml";
    }
    if (baseType.indexOf("text/") === 0) {
      return "text";
    }
    return "";
  }
})();
