Instagram Unhook

A userscript to help people escape Instagram addiction. After installation, a small gear icon will appear on Instagram in the bottom right corner. There, you can set various tools/schedules to reduce your exposure to the algorithm. Currently, you can enable/disable messaging, a chronological/algorithmic feed, and instagram stories, and you can disable the blocker entirely. You can also set a schedule for working hours to have certain features appear and dissapear. Best of luck and fuck you Meta!

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Instagram Unhook
// @namespace    instagram-unhook
// @version      1.6.3
// @description  A userscript to help people escape Instagram addiction. After installation, a small gear icon will appear on Instagram in the bottom right corner. There, you can set various tools/schedules to reduce your exposure to the algorithm. Currently, you can enable/disable messaging, a chronological/algorithmic feed, and instagram stories, and you can disable the blocker entirely. You can also set a schedule for working hours to have certain features appear and dissapear. Best of luck and fuck you Meta!
// @match        https://www.instagram.com/*
// @run-at       document-start
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_addStyle
// @grant        GM_registerMenuCommand
// @license      MIT-0
// ==/UserScript==

(() => {
  // src/lib.js
  var clamp = (n, min, max) => Math.max(min, Math.min(max, n));
  var pad2 = (n) => String(n).padStart(2, "0");
  var hhmmToMins = (s) => {
    const m = /^(\d{1,2}):(\d{2})$/.exec(String(s).trim());
    if (!m) return 0;
    return clamp(+m[1], 0, 23) * 60 + clamp(+m[2], 0, 59);
  };
  var dayOfWeek = (d = /* @__PURE__ */ new Date()) => {
    const n = d.getDay();
    return n === 0 ? 7 : n;
  };
  var sameOrigin = (u, origin) => {
    try {
      return new URL(u, origin).origin === origin;
    } catch {
      return false;
    }
  };
  var pathOf = (u, origin) => {
    try {
      return new URL(u, origin).pathname;
    } catch {
      return "";
    }
  };
  var isDMPath = (p) => p.startsWith("/direct");
  var isLoginFlowPath = (p) => /^\/(accounts|challenge|oauth)(\/|$)/.test(p);
  var isPostDetail = (p) => /^\/p\/[^/]+/.test(p);
  var isStoriesViewer = (p) => /^\/stories(\/|$)/.test(p);
  var isReelsPath = (p) => /^\/reels(\/|$)/.test(p);
  var isExplorePath = (p) => /^\/explore(\/|$)/.test(p);
  var isRoot = (pathname) => pathname === "/";
  var onFollowing = (search) => search.startsWith("?variant=following");
  var KNOWN_PREFIXES = /^\/(p|reel|reels|stories|direct|accounts|challenge|oauth|explore|about|emails|session|api|static|developer|legal|terms|privacy|safety|tags|locations|nametag)(\/|$)/;
  var isProfilePath = (p) => {
    if (!p || p === "/") return false;
    if (KNOWN_PREFIXES.test(p)) return false;
    return /^\/[a-zA-Z0-9._]{1,30}\/?$/.test(p);
  };
  var isWeekend = (n) => n === 6 || n === 7;
  var cloneF = (f) => ({
    messages: !!f.messages,
    chronological: !!f.chronological,
    stories: !!f.stories,
    unrestricted: !!f.unrestricted,
    allowProfiles: !!f.allowProfiles,
    allowSearch: !!f.allowSearch,
    allowNotifications: !!f.allowNotifications,
    allowReels: !!f.allowReels,
    allowCreate: !!f.allowCreate,
    allowDMPosts: !!f.allowDMPosts
  });
  var eqF = (a, b) => a.messages === b.messages && a.chronological === b.chronological && a.stories === b.stories && !!a.unrestricted === !!b.unrestricted && !!a.allowProfiles === !!b.allowProfiles && !!a.allowSearch === !!b.allowSearch && !!a.allowNotifications === !!b.allowNotifications && !!a.allowReels === !!b.allowReels && !!a.allowCreate === !!b.allowCreate && !!a.allowDMPosts === !!b.allowDMPosts;
  var DM_INBOX_URL = "https://www.instagram.com/direct/inbox/";
  var FOLLOWING_URL = "https://www.instagram.com/?variant=following";
  var STORY_FLAG_SS = "iuStoriesOnly";
  var STORY_HASH = "#iu_so";
  var SETTINGS_KEY = "iu_settings_v2";
  var DEFAULTS = {
    version: 2,
    debug: true,
    persistOverrideAcrossSessions: true,
    schedule: {
      weekdays: {
        rangeStart: "09:00",
        rangeEnd: "19:00",
        inRange: { messages: true, chronological: false, stories: false, unrestricted: false, allowProfiles: false, allowSearch: false, allowNotifications: false, allowReels: false, allowCreate: false, allowDMPosts: false },
        outRange: { messages: true, chronological: true, stories: true, unrestricted: false, allowProfiles: true, allowSearch: true, allowNotifications: true, allowReels: false, allowCreate: true, allowDMPosts: true }
      },
      weekends: {
        rangeStart: "00:00",
        rangeEnd: "00:00",
        inRange: { messages: true, chronological: true, stories: true, unrestricted: false, allowProfiles: true, allowSearch: true, allowNotifications: true, allowReels: false, allowCreate: true, allowDMPosts: true },
        outRange: { messages: true, chronological: true, stories: true, unrestricted: false, allowProfiles: true, allowSearch: true, allowNotifications: true, allowReels: false, allowCreate: true, allowDMPosts: true }
      }
    },
    override: {
      active: false,
      features: { messages: false, chronological: false, stories: false, unrestricted: false, allowProfiles: false, allowSearch: false, allowNotifications: false, allowReels: false, allowCreate: false, allowDMPosts: false },
      expiresAt: null
    },
    sidebar: { dashboard: false, more: true, fromMeta: true },
    scheduleEnabled: true,
    feedMode: "chronological"
  };
  function normalizeRangesForDay(kind, schedule) {
    const conf = schedule[kind];
    const s = hhmmToMins(conf.rangeStart), e = hhmmToMins(conf.rangeEnd);
    const inR = cloneF(conf.inRange), outR = cloneF(conf.outRange);
    if (s === e) return [{ start: 0, end: 1440, f: outR }];
    if (s < e) return [{ start: 0, end: s, f: outR }, { start: s, end: e, f: inR }, { start: e, end: 1440, f: outR }];
    return [{ start: 0, end: e, f: inR }, { start: e, end: s, f: outR }, { start: s, end: 1440, f: inR }];
  }
  function getScheduledFAt(schedule, d = /* @__PURE__ */ new Date()) {
    const dn = dayOfWeek(d);
    const mins = d.getHours() * 60 + d.getMinutes();
    const kind = isWeekend(dn) ? "weekends" : "weekdays";
    const blocks = normalizeRangesForDay(kind, schedule);
    let f = blocks.find((b) => mins >= b.start && mins < b.end)?.f;
    if (!f) f = blocks[blocks.length - 1].f;
    return cloneF(f);
  }
  function getNextBoundaryAfter(schedule, d = /* @__PURE__ */ new Date()) {
    const start = new Date(d.getTime());
    const curr = getScheduledFAt(schedule, start);
    for (let i = 0; i < 8; i++) {
      const day = new Date(start.getTime());
      day.setDate(start.getDate() + i);
      const kind = isWeekend(dayOfWeek(day)) ? "weekends" : "weekdays";
      for (const b of normalizeRangesForDay(kind, schedule)) {
        const t = new Date(day.getFullYear(), day.getMonth(), day.getDate(), Math.floor(b.start / 60), b.start % 60, 0, 0);
        if (t <= d) continue;
        if (!eqF(getScheduledFAt(schedule, t), curr)) return t;
      }
    }
    const fb = new Date(d.getTime() + 864e5);
    fb.setSeconds(0, 0);
    return fb;
  }
  function checkAccess(f, p, options = {}) {
    const { allowLoginFlows = true, sourcePath = null } = options;
    if (f.unrestricted) return { allowed: true, reason: "unrestricted" };
    if (isDMPath(p)) return { allowed: true, reason: "dm" };
    if (allowLoginFlows && isLoginFlowPath(p)) return { allowed: true, reason: "login" };
    if (isPostDetail(p)) {
      if (f.chronological || f.stories) return { allowed: true, reason: "post-detail" };
      if (f.allowDMPosts && sourcePath && isDMPath(sourcePath)) return { allowed: true, reason: "dm-post-allowed" };
    }
    if (f.stories && isStoriesViewer(p)) return { allowed: true, reason: "stories-viewer" };
    if (f.allowProfiles && isProfilePath(p)) return { allowed: true, reason: "profile-allowed" };
    if (isExplorePath(p)) {
      if (f.allowSearch) return { allowed: true, reason: "search-allowed" };
      return { allowed: false, reason: "search-blocked" };
    }
    if (isReelsPath(p)) {
      if (f.allowReels) return { allowed: true, reason: "reels-allowed" };
      return { allowed: false, reason: "reels-blocked" };
    }
    const hybrid = f.messages && (f.chronological || f.stories);
    if (hybrid) {
      if (p === "/") return { allowed: true, reason: "hybrid-home" };
      return { allowed: false, reason: "hybrid-block-nonhome" };
    }
    if (f.messages && !hybrid) return { allowed: false, reason: "pure-messages" };
    const hasNonFeedFeature = f.allowReels || f.allowSearch || f.allowNotifications || f.allowCreate || f.allowProfiles;
    if (hasNonFeedFeature && !f.chronological && !f.stories && !f.messages && p === "/") {
      return { allowed: false, reason: "no-feed-redirect" };
    }
    return { allowed: true, reason: "default-allow" };
  }
  var landingForHybrid = (f) => f.chronological ? FOLLOWING_URL : "/";
  function describeF(f) {
    if (f.unrestricted) return "Unrestricted";
    const p = [];
    if (f.messages) p.push("Msg");
    if (f.chronological) p.push("Feed");
    if (f.stories) p.push("Stories");
    if (f.allowProfiles) p.push("Profiles");
    if (f.allowSearch) p.push("Search");
    if (f.allowNotifications) p.push("Notif");
    if (f.allowReels) p.push("Reels");
    if (f.allowCreate) p.push("Create");
    if (f.allowDMPosts) p.push("DM Posts");
    return p.join(" + ") || "No features";
  }
  var fmtTime = (d) => {
    const dd = new Date(d);
    return `${dd.toLocaleDateString()} ${pad2(dd.getHours())}:${pad2(dd.getMinutes())}`;
  };

  // src/main.js
  var GM = typeof GM_getValue === "function" && typeof GM_setValue === "function" ? {
    get: (k, v) => {
      try {
        return GM_getValue(k, v);
      } catch {
        return v;
      }
    },
    set: (k, v) => {
      try {
        GM_setValue(k, v);
      } catch {
      }
    },
    addStyle: (css) => {
      try {
        GM_addStyle(css);
      } catch {
        const el = document.createElement("style");
        el.textContent = css;
        document.documentElement.appendChild(el);
      }
    },
    registerMenu: (label, fn) => {
      try {
        GM_registerMenuCommand(label, fn);
      } catch {
      }
    }
  } : {
    get: (k, v) => {
      try {
        return JSON.parse(localStorage.getItem(k)) ?? v;
      } catch {
        return v;
      }
    },
    set: (k, v) => {
      try {
        localStorage.setItem(k, JSON.stringify(v));
      } catch {
      }
    },
    addStyle: (css) => {
      const el = document.createElement("style");
      el.textContent = css;
      (document.head || document.documentElement || document.body || document).appendChild(el);
    },
    registerMenu: () => {
    }
  };
  var now = () => /* @__PURE__ */ new Date();
  var navReplace = (url) => {
    if (window.__iu_test_nav) {
      window.__iu_test_nav.push({ type: "replace", url });
      return;
    }
    location.replace(url);
  };
  var navAssign = (url) => {
    if (window.__iu_test_nav) {
      window.__iu_test_nav.push({ type: "assign", url });
      return;
    }
    location.assign(url);
  };
  var settings = (function() {
    const s = GM.get(SETTINGS_KEY, null);
    if (!s || s.version !== DEFAULTS.version) {
      GM.set(SETTINGS_KEY, DEFAULTS);
      return JSON.parse(JSON.stringify(DEFAULTS));
    }
    return s;
  })();
  function saveSettings() {
    GM.set(SETTINGS_KEY, settings);
  }
  var dbg = {
    on: !!settings.debug,
    log(tag, msg, extra) {
      if (!this.on) return;
      try {
        console.log(`[IU] ${tag} :: ${msg}`, extra ?? "");
      } catch {
      }
    },
    group(tag, obj) {
      if (!this.on) return;
      try {
        console.groupCollapsed(`[IU] ${tag}`);
        if (obj) console.log(obj);
        console.groupEnd();
      } catch {
      }
    }
  };
  window.IU = {
    version: "1.6.3",
    get settings() {
      return JSON.parse(JSON.stringify(settings));
    },
    state() {
      return { features: current.features, nextBoundary: current.nextBoundary };
    },
    toggleDebug(on) {
      settings.debug = !!on;
      saveSettings();
      dbg.on = settings.debug;
      console.info("[IU] debug", dbg.on ? "ENABLED" : "disabled");
    },
    setOverride(f) {
      const exp = computeNextSwitchTime();
      settings.override = { active: true, features: f, expiresAt: exp.toISOString() };
      saveSettings();
      current.features = getActiveFeatures();
      current.nextBoundary = exp;
      applyPolicyForLocation();
      dbg.group("IU.setOverride", { f, exp });
    },
    clearOverride() {
      settings.override.active = false;
      settings.override.expiresAt = null;
      saveSettings();
      current.features = getActiveFeatures();
      current.nextBoundary = computeNextSwitchTime();
      applyPolicyForLocation();
      dbg.group("IU.clearOverride");
    },
    forceApply() {
      applyPolicyForLocation();
      dbg.group("IU.forceApply");
    },
    setFeedMode(mode) {
      settings.feedMode = mode;
      saveSettings();
    }
  };
  var setSOIntent = () => {
    try {
      sessionStorage.setItem(STORY_FLAG_SS, "1");
    } catch {
    }
  };
  var inSO = () => sessionStorage.getItem(STORY_FLAG_SS) === "1";
  var clearSOIntent = () => {
    try {
      sessionStorage.removeItem(STORY_FLAG_SS);
    } catch {
    }
  };
  var hasAndConsumeSOFromURL = () => {
    if (location.hash === STORY_HASH) {
      history.replaceState(history.state, "", location.pathname + location.search);
      return true;
    }
    return false;
  };
  var consumeSOIntent = () => {
    const s = inSO() || hasAndConsumeSOFromURL();
    if (s) sessionStorage.setItem(STORY_FLAG_SS, "1");
    return s;
  };
  function getActiveFeatures() {
    if (settings.override?.active) {
      const exp = settings.override.expiresAt ? new Date(settings.override.expiresAt) : null;
      if (!exp || now() < exp) return cloneF(settings.override.features);
      settings.override.active = false;
      settings.override.expiresAt = null;
      saveSettings();
      dbg.log("Override", "expired");
    }
    return getScheduledFAt(settings.schedule);
  }
  function computeNextSwitchTime() {
    return getNextBoundaryAfter(settings.schedule, now());
  }
  var current = { features: getActiveFeatures(), nextBoundary: computeNextSwitchTime() };
  dbg.group("Startup", current);
  var boundaryTimer = null;
  function scheduleTick() {
    if (boundaryTimer) clearTimeout(boundaryTimer);
    const ms = Math.max(1e3, Math.min(864e5, current.nextBoundary - now()));
    boundaryTimer = setTimeout(() => {
      current.features = getActiveFeatures();
      current.nextBoundary = computeNextSwitchTime();
      dbg.group("Boundary tick", current);
      applyPolicyForLocation();
      toast(`Instagram Unhook \u2192 ${describeF(current.features)} (until ${fmtTime(current.nextBoundary)})`);
      scheduleTick();
      refreshUI();
    }, ms);
  }
  GM.addStyle(`
  .iu-block-all body { opacity:0 !important; pointer-events:none !important; }
  .iu-stories-only main article { display:none !important; }
  .iu-hide-stories-tray [aria-label^="Story by"] { display:none !important; }
  .iu-hide-stories-tray [aria-label="Stories"] { display:none !important; height:0 !important; }
  .iu-toast{position:fixed;z-index:2147483647;left:50%;transform:translateX(-50%);bottom:24px;background:#111;color:#fff;padding:10px 14px;border-radius:10px;font:12px/1.4 system-ui,-apple-system,Segoe UI,Roboto,sans-serif;box-shadow:0 6px 30px rgba(0,0,0,.35);opacity:.95;max-width:calc(100vw - 28px);text-align:center;}
  .iu-gear{position:fixed;z-index:2147483647;right:max(18px, env(safe-area-inset-right,18px));bottom:max(72px, calc(env(safe-area-inset-bottom,18px) + 54px));width:44px;height:44px;border-radius:50%;background:#111;color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 6px 30px rgba(0,0,0,.35);-webkit-tap-highlight-color:transparent;touch-action:manipulation;font-size:20px;}
  .iu-panel-backdrop{position:fixed;inset:0;background:rgba(0,0,0,.35);z-index:2147483646;touch-action:none;}
  .iu-panel{position:fixed;right:max(12px, env(safe-area-inset-right,12px));top:max(12px, env(safe-area-inset-top,12px));bottom:max(70px, calc(env(safe-area-inset-bottom,12px) + 58px));width:360px;max-width:min(420px, calc(100vw - 24px));overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;background:#fff;color:#111;border-radius:14px;box-shadow:0 20px 50px rgba(0,0,0,.25);padding:16px;z-index:2147483647;font:13px/1.4 system-ui,-apple-system,Segoe UI,Roboto,sans-serif;box-sizing:border-box;}
  .iu-body-locked{overflow:hidden !important;position:fixed !important;width:100% !important;}
  .iu-panel *{box-sizing:border-box}
  .iu-row{display:flex;gap:8px;align-items:center;margin:6px 0;flex-wrap:wrap}
  .iu-sec{border-top:1px solid #eee;margin-top:10px;padding-top:10px}
  .iu-h{font-weight:700;font-size:14px;margin-bottom:6px}
  .iu-panel .iu-btn{all:unset;display:inline-block;padding:6px 10px;border-radius:8px;border:1px solid #ddd;background:#fafafa;cursor:pointer;white-space:nowrap;font:13px/1.2 system-ui,-apple-system,Segoe UI,Roboto,sans-serif !important;color:#111 !important;-webkit-appearance:none;appearance:none}
  .iu-panel .iu-btn.primary{background:#111;border-color:#111;color:#fff !important}
  .iu-grid{display:grid;grid-template-columns:auto 1fr;gap:6px 10px}
  .iu-note{color:#666;font-size:12px}
  .iu-kbd{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;background:#f1f1f1;padding:1px 4px;border-radius:4px;border:1px solid #ddd}
  .iu-pill{display:inline-flex;align-items:center;gap:4px;padding:4px 10px;border-radius:20px;border:1px solid #ddd;background:#fafafa;cursor:pointer;font:12px/1.2 system-ui,-apple-system,sans-serif;color:#111;-webkit-user-select:none;user-select:none}
  .iu-pill input{margin:0}
  .iu-pill.on{background:#111;color:#fff;border-color:#111}
  .iu-sched-block{background:#f8f8f8;border-radius:10px;padding:10px 12px;margin:6px 0}
  .iu-sched-block .iu-row{margin:4px 0}
  .iu-sched-label{font-weight:600;font-size:12px;color:#666;margin-bottom:2px}
  [data-iu-hide]{display:none !important;height:0 !important;margin:0 !important;padding:0 !important;overflow:hidden !important}
  .iu-disabled-overlay{position:fixed;inset:0;z-index:2147483645;background:#fafafa;display:flex;flex-direction:column;align-items:center;justify-content:center;font:16px/1.6 system-ui,-apple-system,Segoe UI,Roboto,sans-serif;color:#666;text-align:center;padding:24px}
  .iu-disabled-overlay b{font-size:20px;color:#111;display:block;margin-bottom:8px}
  .iu-feat{display:block;padding:5px 0;cursor:pointer;font:13px/1.3 system-ui,-apple-system,sans-serif}
  .iu-feat input[type="checkbox"]{margin:0 6px 0 0;vertical-align:middle}
  .iu-sub{margin:4px 0 2px 22px;font-size:12px;color:#555}
  .iu-sub label{display:block;padding:2px 0;cursor:pointer}
  .iu-sub.disabled{opacity:.4;pointer-events:none}
  .iu-collapse-btn{background:none;border:none;color:#0095f6;cursor:pointer;font:13px/1.3 system-ui,-apple-system,sans-serif;padding:0;text-decoration:underline}
`);
  if (!getActiveFeatures().stories && sessionStorage.getItem(STORY_FLAG_SS)) {
    dbg.log("Early", "Clearing stories intent (Stories OFF)");
    clearSOIntent();
  }
  {
    const chk = checkAccess(current.features, location.pathname);
    dbg.log("Early-Access", `${chk.allowed ? "allow" : "BLOCK"} @${location.pathname}`, chk.reason);
    if (!chk.allowed) {
      document.documentElement.classList.add("iu-block-all");
      const dest = getLanding(current.features);
      if (location.href !== dest) navReplace(dest);
    }
  }
  {
    const f = current.features;
    const wantsChrono = !f.unrestricted && f.chronological && settings.feedMode !== "algorithmic";
    const wantsAlgo = !f.unrestricted && f.chronological && settings.feedMode === "algorithmic";
    if (wantsAlgo && isRoot(location.pathname) && onFollowing(location.search)) {
      dbg.log("Early", "Algorithmic mode \u2192 redirect away from Following");
      navReplace("/");
    } else if (wantsChrono && isRoot(location.pathname) && !onFollowing(location.search)) {
      if (f.stories) {
        if (!inSO() && !hasAndConsumeSOFromURL()) {
          dbg.log("Early", "Chrono+Stories but no intent \u2192 Following");
          navReplace(FOLLOWING_URL);
        }
      } else {
        if (inSO()) {
          dbg.log("Early", "Chrono only \u2192 clear stories intent");
          clearSOIntent();
        }
        dbg.log("Early", "Chrono only \u2192 Following");
        navReplace(FOLLOWING_URL);
      }
    }
  }
  function gotoDM(reason = "") {
    try {
      sessionStorage.setItem("iu_reason", reason);
    } catch {
    }
    if (location.href !== DM_INBOX_URL) navReplace(DM_INBOX_URL);
  }
  var blockContent = (on) => document.documentElement.classList.toggle("iu-block-all", !!on);
  var applySOClass = (on) => document.documentElement.classList.toggle("iu-stories-only", !!on);
  function wireAnchors(root = document) {
    root.querySelectorAll("a[href]:not([data-iu-wired])").forEach((a) => {
      a.dataset.iuWired = "1";
      a.addEventListener("click", (ev) => {
        const href = a.getAttribute("href") || "";
        if (!href || !sameOrigin(href, location.origin)) return;
        const p = pathOf(href, location.origin);
        const f = current.features;
        if (f.allowNotifications) {
          const isNotifEl = a.getAttribute("aria-label") === "Notifications" || a.closest('[aria-label="Notifications"]');
          if (isNotifEl) return;
        }
        const chk = checkAccess(f, p, { sourcePath: location.pathname });
        if (!chk.allowed) {
          ev.preventDefault();
          ev.stopImmediatePropagation();
          dbg.log("Anchor", "BLOCK", { p, reason: chk.reason });
          if (f.messages && !(f.chronological || f.stories)) {
            blockContent(true);
            gotoDM(`click:${p}`);
          } else {
            navAssign(landingForHybrid(f));
          }
          return;
        }
        if (!f.unrestricted && p === "/") {
          ev.preventDefault();
          ev.stopImmediatePropagation();
          if (f.chronological) {
            clearSOIntent();
            applySOClass(false);
            dbg.log("Anchor", "Home \u2192 Following (chronological preferred)");
            navAssign(FOLLOWING_URL);
          } else if (f.stories) {
            setSOIntent();
            applySOClass(true);
            dbg.log("Anchor", "Home \u2192 stories-only");
            navAssign("/");
          } else {
            dbg.log("Anchor", "Home pass-through");
            navAssign("/");
          }
          return;
        }
      }, { capture: true });
    });
  }
  wireAnchors();
  var bigMO = new MutationObserver((m) => {
    try {
      for (const rec of m) for (const n of rec.addedNodes || []) {
        if (n.nodeType === 1) {
          wireAnchors(n);
          applySidebarPolicy(current.features);
        }
      }
    } catch {
    }
  });
  bigMO.observe(document.documentElement, { childList: true, subtree: true });
  (function hookHistory() {
    const wrap = (fn) => function(...args) {
      const rv = fn.apply(this, args);
      queueMicrotask(() => {
        dbg.log("History", `${fn.name} \u2192 policy`);
        applyPolicyForLocation();
      });
      return rv;
    };
    history.pushState = wrap(history.pushState.bind(history));
    history.replaceState = wrap(history.replaceState.bind(history));
  })();
  window.addEventListener("popstate", () => {
    dbg.log("History", "popstate \u2192 policy");
    applyPolicyForLocation();
  });
  if (document.readyState === "loading") {
    window.addEventListener("DOMContentLoaded", () => {
      buildUI();
      refreshUI();
    });
  } else {
    buildUI();
    refreshUI();
  }
  function getLanding(f) {
    if (f.allowReels && !f.chronological && !f.stories && !f.messages) return "https://www.instagram.com/reels/";
    if (f.messages && !f.chronological && !f.stories) return DM_INBOX_URL;
    if (f.allowSearch && !f.chronological && !f.stories && !f.messages) return "https://www.instagram.com/explore/";
    if (f.chronological && settings.feedMode === "chronological") return FOLLOWING_URL;
    return "/";
  }
  function applyPolicyForLocation() {
    const f = current.features;
    dbg.group("ApplyPolicy", { path: location.pathname + location.search + location.hash, features: f, inSO: inSO() });
    if (!f.stories && inSO()) {
      dbg.log("Policy", "Stories OFF \u2192 clear intent");
      clearSOIntent();
      applySOClass(false);
      stopSOHiding();
    }
    const chk = checkAccess(f, location.pathname, { sourcePath: location.pathname });
    dbg.log("Policy-Access", `${chk.allowed ? "allow" : "BLOCK"}`, chk.reason);
    if (!chk.allowed) {
      blockContent(true);
      const dest = getLanding(f);
      if (location.href !== dest) navReplace(dest);
      return;
    } else {
      blockContent(false);
    }
    const wantsChrono = f.chronological && settings.feedMode !== "algorithmic";
    const wantsAlgo = f.chronological && settings.feedMode === "algorithmic";
    if (!f.unrestricted && isRoot(location.pathname)) {
      if (wantsAlgo && onFollowing(location.search)) {
        applySOClass(false);
        dbg.log("Policy", "algorithmic mode \u2192 redirect away from Following");
        navReplace("/");
        return;
      }
      if (f.stories && !f.chronological) {
        setSOIntent();
        applySOClass(true);
        startSOHiding();
        dbg.log("Policy", "stories-only (no feed)");
      } else if (f.stories && !onFollowing(location.search) && !wantsAlgo) {
        const so = consumeSOIntent();
        if (so || inSO()) {
          applySOClass(true);
          startSOHiding();
          dbg.log("Policy", "stories-only on Home");
        } else if (wantsChrono) {
          applySOClass(false);
          dbg.log("Policy", "chronological \u2192 Following");
          navReplace(FOLLOWING_URL);
          return;
        } else {
          applySOClass(false);
        }
      } else if (wantsChrono && !onFollowing(location.search)) {
        applySOClass(false);
        clearSOIntent();
        stopSOHiding();
        dbg.log("Policy", "chronological only \u2192 Following");
        navReplace(FOLLOWING_URL);
        return;
      } else {
        applySOClass(false);
        clearSOIntent();
        stopSOHiding();
      }
    } else {
      applySOClass(false);
      if (!f.stories) {
        clearSOIntent();
        stopSOHiding();
      }
    }
    applySidebarPolicy(f);
    showDisabledOverlay(f);
  }
  function hasAnyFeature(f) {
    return f && (f.unrestricted || f.messages || f.chronological || f.stories || f.allowProfiles || f.allowSearch || f.allowNotifications || f.allowReels || f.allowCreate || f.allowDMPosts);
  }
  var disabledOverlay = null;
  function showDisabledOverlay(f) {
    const shouldShow = !hasAnyFeature(f);
    if (shouldShow && !disabledOverlay) {
      disabledOverlay = document.createElement("div");
      disabledOverlay.className = "iu-disabled-overlay";
      disabledOverlay.innerHTML = "<b>Instagram Unhook</b>All Instagram features are currently disabled.<br>Click the gear icon to enable features.";
      document.documentElement.appendChild(disabledOverlay);
    } else if (!shouldShow && disabledOverlay) {
      disabledOverlay.remove();
      disabledOverlay = null;
    }
  }
  function toggleHide(el, hide) {
    if (!el || el.closest(".iu-panel, .iu-gear")) return;
    if (hide) el.setAttribute("data-iu-hide", "");
    else el.removeAttribute("data-iu-hide");
  }
  function hideNavItem(selector, show) {
    document.querySelectorAll(selector).forEach((el) => {
      const link = el.closest('a, [role="link"], [role="button"], [role="menuitem"]') || el;
      const container = link.parentElement || link;
      toggleHide(container, !show);
    });
  }
  function applySidebarPolicy(f) {
    if (!f) return;
    hideNavItem('a[href="/"]', f.chronological || f.stories || f.unrestricted);
    hideNavItem('a[href^="/direct"]', f.messages);
    hideNavItem('[aria-label="Search"]', f.allowSearch);
    hideNavItem('a[href^="/explore"]', f.allowSearch);
    hideNavItem('[aria-label="Notifications"]', f.allowNotifications);
    hideNavItem('a[href^="/reels"]', f.allowReels);
    hideNavItem('[aria-label="New post"], [aria-label="Create"]', f.allowCreate);
    hideFeedTabs(f);
    hideStoriesTray(f);
    hideFloatingMessages(f);
    hideSidebarExtras(settings.sidebar);
  }
  function hideFeedTabs(f) {
    if (!f) return;
    const feedOff = !f.chronological && !f.unrestricted;
    const isAlgo = f.chronological && settings.feedMode === "algorithmic";
    const isChrono = f.chronological && settings.feedMode !== "algorithmic";
    const hideForYou = feedOff || isChrono;
    const hideFollowing = feedOff || isAlgo;
    try {
      const selectors = '[role="tablist"] a, [role="tablist"] [role="tab"], [role="tab"], header a, header [role="button"]';
      document.querySelectorAll(selectors).forEach((el) => {
        const text = el.textContent?.trim() || "";
        if (/^\s*for you\s*$/i.test(text)) toggleHide(el, hideForYou);
        if (/^\s*following\s*$/i.test(text)) toggleHide(el, hideFollowing);
      });
    } catch {
    }
  }
  function hideStoriesTray(f) {
    if (!f) return;
    const hide = !f.stories && !f.unrestricted;
    document.documentElement.classList.toggle("iu-hide-stories-tray", hide);
    try {
      let safeHide = function(el) {
        let target = el.parentElement || el;
        if (target.querySelector && target.querySelector("article")) return;
        toggleHide(target, hide);
        const gp = target.parentElement;
        if (gp && gp.tagName !== "MAIN" && gp.tagName !== "BODY" && !gp.querySelector("article") && gp.children.length === 1) {
          toggleHide(gp, hide);
        }
      };
      document.querySelectorAll('[aria-label^="Story by"], [aria-label^="story by"]').forEach((el) => {
        const tray = el.closest('[role="presentation"], ul, [aria-label="Stories"]');
        if (tray) {
          safeHide(tray);
          return;
        }
        let p = el.parentElement;
        for (let i = 0; i < 6 && p; i++) {
          if (p.tagName === "MAIN" || p.tagName === "BODY") break;
          if (p.children.length > 2) {
            safeHide(p);
            break;
          }
          p = p.parentElement;
        }
      });
      document.querySelectorAll('[role="presentation"]').forEach((el) => {
        if (el.querySelector('[aria-label^="Story by"], [aria-label^="story"], canvas')) {
          safeHide(el);
        }
      });
      document.querySelectorAll('[aria-label="Stories"]').forEach((el) => {
        safeHide(el);
      });
      document.querySelectorAll("main ul, section ul").forEach((ul) => {
        if (ul.querySelector("canvas") && !ul.closest("article")) {
          safeHide(ul);
        }
      });
    } catch {
    }
  }
  function hideFloatingMessages(f) {
    if (!f) return;
    try {
      document.querySelectorAll('div[role="button"]').forEach((el) => {
        const msgLabel = el.querySelector('[aria-label="Messages"]');
        if (msgLabel && !el.closest('nav, [role="navigation"], .iu-panel')) {
          toggleHide(el, true);
        }
      });
    } catch {
    }
  }
  function hideSidebarExtras(sidebarSettings) {
    if (!sidebarSettings) return;
    try {
      let hideTextOutsidePosts = function(pattern, show) {
        document.querySelectorAll("span, a, div").forEach((el) => {
          if (el.closest(".iu-panel, .iu-gear, .iu-toast, main article, article")) return;
          if (el.childElementCount > 3) return;
          const text = el.textContent?.trim() || "";
          if (pattern.test(text)) {
            const link = el.closest('a, [role="link"], [role="button"], [role="menuitem"]') || el;
            const container = link.parentElement || link;
            if (!container.closest(".iu-panel, main article, article")) {
              toggleHide(container, !show);
            }
          }
        });
      };
      hideTextOutsidePosts(/^dashboard$/i, !!sidebarSettings.dashboard);
      document.querySelectorAll('a[href*="dashboard"], a[href*="professional_dashboard"]').forEach((el) => {
        if (el.closest(".iu-panel, main article")) return;
        toggleHide(el.parentElement || el, !sidebarSettings.dashboard);
      });
      hideTextOutsidePosts(/^more$/i, sidebarSettings.more !== false);
      hideNavItem('[aria-label="More"], [aria-label="Settings and activity"]', sidebarSettings.more !== false);
      hideTextOutsidePosts(/^also from meta$/i, sidebarSettings.fromMeta !== false);
      hideTextOutsidePosts(/^from meta$/i, sidebarSettings.fromMeta !== false);
    } catch {
    }
  }
  var soObserver = null;
  function hidePostsOnce() {
    if (!document.documentElement.classList.contains("iu-stories-only")) return;
    document.querySelectorAll("main article").forEach((el) => {
      if (el.dataset.iuHidden) return;
      el.dataset.iuHidden = "1";
      el.style.display = "none";
      el.setAttribute("aria-hidden", "true");
    });
  }
  function startSOHiding() {
    hidePostsOnce();
    if (soObserver || !document.body) return;
    soObserver = new MutationObserver(() => {
      if (inSO()) hidePostsOnce();
    });
    soObserver.observe(document.body, { childList: true, subtree: true });
  }
  function stopSOHiding() {
    if (soObserver) {
      soObserver.disconnect();
      soObserver = null;
    }
    document.querySelectorAll('main article[data-iu-hidden="1"]').forEach((el) => {
      el.style.display = "";
      el.removeAttribute("aria-hidden");
      delete el.dataset.iuHidden;
    });
  }
  var toastTimer = null;
  function toast(msg, dur = 2500) {
    try {
      const old = document.querySelector(".iu-toast");
      if (old) old.remove();
      const t = document.createElement("div");
      t.className = "iu-toast";
      t.textContent = msg;
      document.documentElement.appendChild(t);
      clearTimeout(toastTimer);
      toastTimer = setTimeout(() => t.remove(), dur);
    } catch {
    }
  }
  var gearBtn = null;
  var panel = null;
  var backdrop = null;
  function buildUI() {
    gearBtn = document.createElement("div");
    gearBtn.className = "iu-gear";
    gearBtn.id = "iu-gear";
    gearBtn.title = "Instagram Unhook settings (Alt+U)";
    gearBtn.setAttribute("role", "button");
    gearBtn.setAttribute("aria-label", "Instagram Unhook settings");
    gearBtn.setAttribute("tabindex", "0");
    gearBtn.innerHTML = "\u2699\uFE0F";
    gearBtn.addEventListener("click", openPanel);
    gearBtn.addEventListener("touchend", (e) => {
      e.preventDefault();
      openPanel();
    });
    document.documentElement.appendChild(gearBtn);
    window.addEventListener("keydown", (e) => {
      if (e.altKey && !e.shiftKey && !e.ctrlKey && !e.metaKey && e.key.toLowerCase() === "u") {
        e.preventDefault();
        openPanel();
      }
    });
    GM.registerMenu("Instagram Unhook: Open settings", openPanel);
  }
  function openPanel() {
    if (panel) {
      refreshUI();
      return;
    }
    lockBodyScroll();
    backdrop = document.createElement("div");
    backdrop.className = "iu-panel-backdrop";
    backdrop.addEventListener("click", closePanel);
    backdrop.addEventListener("touchmove", (e) => e.preventDefault(), { passive: false });
    panel = document.createElement("div");
    panel.className = "iu-panel";
    const FEAT_LABELS = [
      ["msg", "Messages"],
      ["chron", "Feed"],
      ["sto", "Stories"],
      ["prof", "Profiles"],
      ["search", "Search"],
      ["notif", "Notifications"],
      ["reels", "Reels"],
      ["create", "Create"],
      ["dmposts", "DM Posts"]
    ];
    const pills = (prefix) => FEAT_LABELS.map(
      ([k, l]) => `<label class="iu-pill"><input type="checkbox" id="${prefix}-${k}"> ${l}</label>`
    ).join("\n            ");
    panel.innerHTML = `
    <div style="display:flex;justify-content:space-between;align-items:baseline">
      <div class="iu-h" style="margin:0">Instagram Unhook</div>
      <span class="iu-note">v1.6.3 &middot; <span class="iu-kbd">Alt+U</span></span>
    </div>
    <div class="iu-grid" style="margin:8px 0"><div>Active:</div><div id="iu-cur" style="font-weight:600"></div><div id="iu-until-label">Until:</div><div id="iu-next"></div></div>

    <div class="iu-sec">
      <div class="iu-h">Features</div>

      <label class="iu-feat"><input type="checkbox" id="iu-ovr-chron"> Feed</label>
      <div class="iu-sub" id="iu-sub-feed">
        <label><input type="radio" name="iu-feed-mode" id="iu-feed-chrono" checked> Chronological</label>
        <label><input type="radio" name="iu-feed-mode" id="iu-feed-algo"> Algorithmic</label>
      </div>

      <label class="iu-feat"><input type="checkbox" id="iu-ovr-sto"> Stories</label>
      <label class="iu-feat"><input type="checkbox" id="iu-ovr-msg"> Messages</label>
      <div class="iu-sub" id="iu-sub-msg">
        <label><input type="checkbox" id="iu-ovr-dmposts"> Allow viewing posts in DMs</label>
      </div>

      <label class="iu-feat"><input type="checkbox" id="iu-ovr-search"> Search & Explore</label>
      <label class="iu-feat"><input type="checkbox" id="iu-ovr-notif"> Notifications</label>
      <label class="iu-feat"><input type="checkbox" id="iu-ovr-reels"> Reels</label>
      <label class="iu-feat"><input type="checkbox" id="iu-ovr-create"> Create</label>
      <label class="iu-feat"><input type="checkbox" id="iu-ovr-prof"> Profiles</label>
      <label class="iu-feat"><input type="checkbox" id="iu-sb-dashboard"> Dashboard</label>
      <label class="iu-feat"><input type="checkbox" id="iu-sb-more"> More menu</label>
      <label class="iu-feat"><input type="checkbox" id="iu-sb-meta"> From Meta</label>

      <div class="iu-row" style="margin-top:10px">
        <button id="iu-ovr-apply" class="iu-btn primary">Apply Changes</button>
        <button id="iu-ovr-none" class="iu-btn">Clear</button>
        <button id="iu-ovr-unr" class="iu-btn">Unrestricted</button>
      </div>
    </div>

    <div class="iu-sec">
      <label class="iu-feat"><input type="checkbox" id="iu-sched-enable"> <b>Enable Schedule</b></label>
      <div id="iu-sched-body" style="display:none;margin-top:8px">
        <div class="iu-sched-block">
          <div class="iu-sched-label">Weekdays</div>
          <div class="iu-row"><span>Hours:</span><input id="iu-wd-start" type="time" step="60" style="width:100px"><span>to</span><input id="iu-wd-end" type="time" step="60" style="width:100px"></div>
          <div class="iu-sched-label" style="margin-top:4px">During hours</div>
          <div id="iu-wd-in" class="iu-row">${pills("iu-wd-in")}</div>
          <div class="iu-sched-label">Outside hours</div>
          <div id="iu-wd-out" class="iu-row">${pills("iu-wd-out")}</div>
        </div>
        <div class="iu-sched-block">
          <div class="iu-sched-label">Weekends</div>
          <div class="iu-row"><span>Hours:</span><input id="iu-we-start" type="time" step="60" style="width:100px"><span>to</span><input id="iu-we-end" type="time" step="60" style="width:100px"></div>
          <div class="iu-sched-label" style="margin-top:4px">During hours</div>
          <div id="iu-we-in" class="iu-row">${pills("iu-we-in")}</div>
          <div class="iu-sched-label">Outside hours</div>
          <div id="iu-we-out" class="iu-row">${pills("iu-we-out")}</div>
        </div>
        <button id="iu-save" class="iu-btn primary" style="margin-top:6px">Save Schedule</button>
      </div>
    </div>

    <div class="iu-sec">
      <div class="iu-row" style="justify-content:space-between">
        <div class="iu-row">
          <label class="iu-pill"><input type="checkbox" id="iu-ovr-persist"> Persist override</label>
          <label class="iu-pill"><input type="checkbox" id="iu-debug"> Debug log</label>
        </div>
        <button id="iu-reset" class="iu-btn">Reset All</button>
      </div>
    </div>`;
    document.documentElement.appendChild(backdrop);
    document.documentElement.appendChild(panel);
    panel.querySelector("#iu-ovr-none").addEventListener("click", () => {
      settings.override.active = false;
      settings.override.expiresAt = null;
      saveSettings();
      current.features = getActiveFeatures();
      current.nextBoundary = computeNextSwitchTime();
      applyPolicyForLocation();
      refreshUI();
      toast("Override cleared");
    });
    panel.querySelector("#iu-ovr-unr").addEventListener("click", () => {
      if (!confirm("Enable Unrestricted? Reels will be available and protections disabled until the next scheduled boundary.")) return;
      const exp = computeNextSwitchTime();
      settings.override = { active: true, features: { messages: true, chronological: true, stories: true, unrestricted: true, allowProfiles: true, allowSearch: true, allowNotifications: true, allowReels: true, allowCreate: true, allowDMPosts: true }, expiresAt: exp.toISOString() };
      saveSettings();
      current.features = getActiveFeatures();
      current.nextBoundary = exp;
      applyPolicyForLocation();
      refreshUI();
      toast("Unrestricted ON");
    });
    panel.querySelector("#iu-ovr-apply").addEventListener("click", () => {
      const feedOn = panel.querySelector("#iu-ovr-chron").checked;
      settings.feedMode = panel.querySelector("#iu-feed-chrono")?.checked ? "chronological" : "algorithmic";
      saveSettings();
      const f = {
        messages: panel.querySelector("#iu-ovr-msg").checked,
        chronological: feedOn,
        stories: panel.querySelector("#iu-ovr-sto").checked,
        unrestricted: false,
        allowProfiles: panel.querySelector("#iu-ovr-prof").checked,
        allowSearch: panel.querySelector("#iu-ovr-search").checked,
        allowNotifications: panel.querySelector("#iu-ovr-notif").checked,
        allowReels: panel.querySelector("#iu-ovr-reels").checked,
        allowCreate: panel.querySelector("#iu-ovr-create").checked,
        allowDMPosts: panel.querySelector("#iu-ovr-dmposts").checked
      };
      const exp = computeNextSwitchTime();
      settings.override = { active: true, features: f, expiresAt: exp.toISOString() };
      saveSettings();
      current.features = getActiveFeatures();
      current.nextBoundary = exp;
      applyPolicyForLocation();
      refreshUI();
      toast(`Override: ${describeF(f)}`);
    });
    panel.querySelector("#iu-ovr-persist").addEventListener("change", (e) => {
      settings.persistOverrideAcrossSessions = !!e.target.checked;
      saveSettings();
    });
    panel.querySelector("#iu-debug").addEventListener("change", (e) => {
      settings.debug = !!e.target.checked;
      saveSettings();
      dbg.on = settings.debug;
      console.info("[IU] debug", dbg.on ? "ENABLED" : "disabled");
    });
    panel.querySelector("#iu-save").addEventListener("click", () => {
      const S = settings.schedule;
      S.weekdays.rangeStart = panel.querySelector("#iu-wd-start").value || "09:00";
      S.weekdays.rangeEnd = panel.querySelector("#iu-wd-end").value || "19:00";
      S.weekdays.inRange = readFeats("iu-wd-in");
      S.weekdays.outRange = readFeats("iu-wd-out");
      S.weekends.rangeStart = panel.querySelector("#iu-we-start").value || "00:00";
      S.weekends.rangeEnd = panel.querySelector("#iu-we-end").value || "00:00";
      S.weekends.inRange = readFeats("iu-we-in");
      S.weekends.outRange = readFeats("iu-we-out");
      saveSettings();
      current.features = getActiveFeatures();
      current.nextBoundary = computeNextSwitchTime();
      applyPolicyForLocation();
      refreshUI();
      toast("Schedule saved");
    });
    panel.querySelector("#iu-reset").addEventListener("click", () => {
      if (!confirm("Reset to defaults?")) return;
      settings = JSON.parse(JSON.stringify(DEFAULTS));
      saveSettings();
      current.features = getActiveFeatures();
      current.nextBoundary = computeNextSwitchTime();
      applyPolicyForLocation();
      refreshUI();
      toast("Defaults restored");
    });
    const feedCb = panel.querySelector("#iu-ovr-chron");
    const msgCb = panel.querySelector("#iu-ovr-msg");
    const updateSubs = () => {
      const feedSub = panel.querySelector("#iu-sub-feed");
      const msgSub = panel.querySelector("#iu-sub-msg");
      if (feedSub) feedSub.classList.toggle("disabled", !feedCb.checked);
      if (msgSub) msgSub.classList.toggle("disabled", !msgCb.checked);
      if (!msgCb.checked) panel.querySelector("#iu-ovr-dmposts").checked = false;
    };
    feedCb.addEventListener("change", updateSubs);
    msgCb.addEventListener("change", updateSubs);
    ["dashboard", "more", "meta"].forEach((key) => {
      const cb = panel.querySelector(`#iu-sb-${key}`);
      if (!cb) return;
      cb.addEventListener("change", () => {
        if (!settings.sidebar) settings.sidebar = {};
        settings.sidebar[key === "meta" ? "fromMeta" : key] = cb.checked;
        saveSettings();
        applySidebarPolicy(current.features);
      });
    });
    const schedEnable = panel.querySelector("#iu-sched-enable");
    const schedBody = panel.querySelector("#iu-sched-body");
    if (schedEnable && schedBody) {
      schedEnable.addEventListener("change", () => {
        settings.scheduleEnabled = schedEnable.checked;
        saveSettings();
        schedBody.style.display = schedEnable.checked ? "" : "none";
      });
    }
    refreshUI();
  }
  var savedScrollY = 0;
  function lockBodyScroll() {
    savedScrollY = window.scrollY;
    document.body.classList.add("iu-body-locked");
    document.body.style.top = `-${savedScrollY}px`;
  }
  function unlockBodyScroll() {
    document.body.classList.remove("iu-body-locked");
    document.body.style.top = "";
    window.scrollTo(0, savedScrollY);
  }
  function closePanel() {
    if (panel) panel.remove();
    panel = null;
    if (backdrop) backdrop.remove();
    backdrop = null;
    unlockBodyScroll();
  }
  function setInput(id, val) {
    const i = panel.querySelector(id);
    if (!i) return;
    i.checked = !!val;
    const pill = i.closest(".iu-pill");
    if (pill) pill.classList.toggle("on", !!val);
  }
  function setTime(id, val) {
    const i = panel.querySelector(id);
    if (i) i.value = val;
  }
  function readFeats(prefix) {
    return {
      messages: panel.querySelector(`#${prefix}-msg`).checked,
      chronological: panel.querySelector(`#${prefix}-chron`).checked,
      stories: panel.querySelector(`#${prefix}-sto`).checked,
      unrestricted: false,
      allowProfiles: panel.querySelector(`#${prefix}-prof`).checked,
      allowSearch: panel.querySelector(`#${prefix}-search`).checked,
      allowNotifications: panel.querySelector(`#${prefix}-notif`).checked,
      allowReels: panel.querySelector(`#${prefix}-reels`).checked,
      allowCreate: panel.querySelector(`#${prefix}-create`).checked,
      allowDMPosts: panel.querySelector(`#${prefix}-dmposts`).checked
    };
  }
  function writeFeats(prefix, f) {
    setInput(`#${prefix}-msg`, f.messages);
    setInput(`#${prefix}-chron`, f.chronological);
    setInput(`#${prefix}-sto`, f.stories);
    setInput(`#${prefix}-prof`, f.allowProfiles);
    setInput(`#${prefix}-search`, f.allowSearch);
    setInput(`#${prefix}-notif`, f.allowNotifications);
    setInput(`#${prefix}-reels`, f.allowReels);
    setInput(`#${prefix}-create`, f.allowCreate);
    setInput(`#${prefix}-dmposts`, f.allowDMPosts);
  }
  function refreshUI() {
    if (!panel) return;
    panel.querySelector("#iu-cur").textContent = describeF(current.features);
    const untilLabel = panel.querySelector("#iu-until-label");
    const untilVal = panel.querySelector("#iu-next");
    if (settings.scheduleEnabled) {
      untilVal.textContent = fmtTime(current.nextBoundary);
      if (untilLabel) untilLabel.style.display = "";
      untilVal.style.display = "";
    } else {
      if (untilLabel) untilLabel.style.display = "none";
      untilVal.style.display = "none";
    }
    const S = settings.schedule;
    setTime("#iu-wd-start", S.weekdays.rangeStart);
    setTime("#iu-wd-end", S.weekdays.rangeEnd);
    writeFeats("iu-wd-in", S.weekdays.inRange);
    writeFeats("iu-wd-out", S.weekdays.outRange);
    setTime("#iu-we-start", S.weekends.rangeStart);
    setTime("#iu-we-end", S.weekends.rangeEnd);
    writeFeats("iu-we-in", S.weekends.inRange);
    writeFeats("iu-we-out", S.weekends.outRange);
    const weSame = S.weekends.rangeStart === S.weekends.rangeEnd;
    const weNote = panel.querySelector("#iu-we-note");
    if (weNote) weNote.style.display = weSame ? "" : "none";
    setInput("#iu-ovr-persist", !!settings.persistOverrideAcrossSessions);
    setInput("#iu-debug", !!settings.debug);
    const ov = settings.override || {};
    writeFeats("iu-ovr", ov.features || {});
    const sb = settings.sidebar || {};
    const sbDash = panel.querySelector("#iu-sb-dashboard");
    if (sbDash) sbDash.checked = !!sb.dashboard;
    const sbMore = panel.querySelector("#iu-sb-more");
    if (sbMore) sbMore.checked = sb.more !== false;
    const sbMeta = panel.querySelector("#iu-sb-meta");
    if (sbMeta) sbMeta.checked = sb.fromMeta !== false;
    const schedEnable = panel.querySelector("#iu-sched-enable");
    const schedBody = panel.querySelector("#iu-sched-body");
    if (schedEnable && schedBody) {
      schedEnable.checked = !!settings.scheduleEnabled;
      schedBody.style.display = settings.scheduleEnabled ? "" : "none";
    }
    const feedChrono = panel.querySelector("#iu-feed-chrono");
    const feedAlgo = panel.querySelector("#iu-feed-algo");
    if (feedChrono && feedAlgo) {
      const isChron = settings.feedMode !== "algorithmic";
      feedChrono.checked = isChron;
      feedAlgo.checked = !isChron;
    }
    const feedSub = panel.querySelector("#iu-sub-feed");
    const msgSub = panel.querySelector("#iu-sub-msg");
    const feedOn = panel.querySelector("#iu-ovr-chron")?.checked;
    const msgOn = panel.querySelector("#iu-ovr-msg")?.checked;
    if (feedSub) feedSub.classList.toggle("disabled", !feedOn);
    if (msgSub) msgSub.classList.toggle("disabled", !msgOn);
    panel.querySelectorAll('.iu-pill input[type="checkbox"]').forEach((cb) => {
      if (cb.dataset.iuWiredPill) return;
      cb.dataset.iuWiredPill = "1";
      cb.addEventListener("change", () => cb.closest(".iu-pill")?.classList.toggle("on", cb.checked));
    });
  }
  scheduleTick();
  applyPolicyForLocation();
  new MutationObserver(() => {
    try {
      if (isRoot(location.pathname) && inSO()) startSOHiding();
      else stopSOHiding();
    } catch {
    }
  }).observe(document.documentElement, { childList: true, subtree: true });
})();