Lemmy Universal Link Switcher

Ensures that all URLs to Lemmy instances always point to your main/home instance.

当前为 2023-07-01 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

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

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name			Lemmy Universal Link Switcher
// @namespace		http://azzurite.tv/
// @license			GPLv3
// @version			1.2.0
// @description		Ensures that all URLs to Lemmy instances always point to your main/home instance.
// @homepageURL		https://gitlab.com/azzurite/lemmy-universal-link-switcher
// @supportURL		https://gitlab.com/azzurite/lemmy-universal-link-switcher/-/issues
// @author			Azzurite
// @match			*://*/*
// @icon			https://gitlab.com/azzurite/lemmy-universal-link-switcher/-/raw/main/resources/favicon.png?inline=true
// @grant			GM.setValue
// @grant			GM.getValue
// @grant			GM.xmlHttpRequest
// @require			https://unpkg.com/@popperjs/core@2
// @require			https://unpkg.com/tippy.js@6
// ==/UserScript==

(() => {
  // src/debug.js
  var DEBUG = false;
  function debug() {
    if (DEBUG)
      console.debug(`Rewriter | `, ...arguments);
  }
  function trace() {
    if (DEBUG === `trace`)
      console.debug(`Rewriter Trace | `, ...arguments);
  }

  // src/instances.js
  function isLemmyInstance(url) {
    return isInstance(INSTANCES_LEMMY, url);
  }
  function isKbinInstance(url) {
    return isInstance(INSTANCES_KBIN, url);
  }
  function isInstance(instances, url) {
    if (url.origin) {
      return instances.has(url.origin);
    } else {
      return false;
    }
  }
  trace(`Define instances sets start`);
  var INSTANCES_LEMMY = /* @__PURE__ */ new Set([
    "http://changeme_gnv6cavn4bbpwvrpmjs5",
    "http://changeme_qiivckbjhtzuinufzvr2",
    "http://changeme_qiivckbjhtzuinufzvr2",
    "http://kek.henlo.fi",
    "https://0v0.social",
    "https://0xdd.org.ru",
    "https://1337lemmy.com",
    "https://158436977.xyz",
    "https://acqrs.co.uk",
    "https://actuallyruben.nl",
    "https://aggregation.cafe",
    "https://agora.nop.chat",
    "https://aiparadise.moe",
    "https://algebro.xyz",
    "https://anarch.is",
    "https://androiddev.network",
    "https://anime-pub.moe",
    "https://animoe.xyz",
    "https://apollo.town",
    "https://areality.social",
    "https://ascy.mooo.com",
    "https://aulem.org",
    "https://aussie.zone",
    "https://badblocks.rocks",
    "https://baomi.tv",
    "https://baraza.africa",
    "https://bbs.9tail.net",
    "https://bbs.darkwitch.net",
    "https://beehaw.org",
    "https://beer.andma.la",
    "https://beevibes.net",
    "https://bethe.kingofdog.de",
    "https://bigfoot.ninja",
    "https://biglemmowski.win",
    "https://bluuit.org",
    "https://board.minimally.online",
    "https://bolha.social",
    "https://bookwormstory.social",
    "https://booty.world",
    "https://botnet.club",
    "https://bubblesthebunny.com",
    "https://bulletintree.com",
    "https://butts.international",
    "https://c.calciumlabs.com",
    "https://caint.org",
    "https://cavy.rocks",
    "https://centennialstate.social",
    "https://chat.maiion.com",
    "https://cigar.cx",
    "https://civilloquy.com",
    "https://clatter.eu",
    "https://cnvrs.net",
    "https://code4lib.net",
    "https://coeus.sbs",
    "https://communick.news",
    "https://community.adiquaints.moe",
    "https://community.nicfab.it",
    "https://compuverse.uk",
    "https://crystals.rest",
    "https://cubing.social",
    "https://culture0.cc",
    "https://darmok.xyz",
    "https://databend.run",
    "https://dataterm.digital",
    "https://dendarii.alaeron.com",
    "https://derp.foo",
    "https://derpzilla.net",
    "https://dgngrnder.com",
    "https://diggit.xyz",
    "https://digipres.cafe",
    "https://digitalgoblin.uk",
    "https://discuss.icewind.me",
    "https://discuss.jacen.moe",
    "https://discuss.ntfy.sh",
    "https://discuss.online",
    "https://discuss.tchncs.de",
    "https://distress.digital",
    "https://dmv.social",
    "https://donky.social",
    "https://dormi.zone",
    "https://dot.surf",
    "https://drachennetz.com",
    "https://drak.gg",
    "https://drlemmy.net",
    "https://dsilo061298.ddns.net",
    "https://dubvee.org",
    "https://dubvee.org",
    "https://einweckglas.com",
    "https://endlesstalk.org",
    "https://endofti.me",
    "https://eslemmy.es",
    "https://eventfrontier.com",
    "https://eviltoast.org",
    "https://exploding-heads.com",
    "https://f.jbradaric.me",
    "https://fadoverso.pt",
    "https://fanaticus.social",
    "https://fanexus.com",
    "https://fed.rosssi.co.uk",
    "https://feddi.no",
    "https://feddit.at",
    "https://feddit.ch",
    "https://feddit.cl",
    "https://feddit.de",
    "https://feddit.dk",
    "https://feddit.eu",
    "https://feddit.fun",
    "https://feddit.it",
    "https://feddit.jp",
    "https://feddit.nl",
    "https://feddit.nu",
    "https://feddit.nz",
    "https://feddit.pl",
    "https://feddit.ro",
    "https://feddit.site",
    "https://feddit.strike23.de",
    "https://feddit.tech",
    "https://feddit.win",
    "https://feddiverse.org",
    "https://federated.community",
    "https://federated.ninja",
    "https://fedibb.ml",
    "https://fedit.io",
    "https://feditown.com",
    "https://fediverse.love",
    "https://fediverse.ro",
    "https://feedly.j-cloud.uk",
    "https://femboys.bar",
    "https://fenbushi.site",
    "https://fig.systems",
    "https://fjdk.uk",
    "https://fl0w.cc",
    "https://forkk.me",
    "https://foros.fediverso.gal",
    "https://forum.basedcount.com",
    "https://forum.stellarcastle.net",
    "https://freewilltiger.page",
    "https://frig.social",
    "https://geddit.social",
    "https://geddit.social",
    "https://glasstower.nl",
    "https://goddess.name",
    "https://gonelemmy.xyz",
    "https://granitestate.social",
    "https://greg.city",
    "https://group.lt",
    "https://grumpy.schuppentier.club",
    "https://hakbox.social",
    "https://halubilo.social",
    "https://hammerdown.0fucks.nl",
    "https://hc.frorayz.tech",
    "https://heckoverflow.net",
    "https://hoodlem.me",
    "https://hoodratshit.org",
    "https://hqueue.dev",
    "https://hyperfair.link",
    "https://iceorchid.net",
    "https://info.prou.be",
    "https://infosec.pub",
    "https://insane.dev",
    "https://invariant-marxism.red",
    "https://jalim.xyz",
    "https://jamie.moe",
    "https://jemmy.jeena.net",
    "https://ka.tet42.org",
    "https://kale.social",
    "https://keeb.lol",
    "https://keylog.zip",
    "https://kleptonix.com",
    "https://kyu.de",
    "https://l.1in1.net",
    "https://l.biendeo.com",
    "https://l.bxy.sh",
    "https://l.jugregator.org",
    "https://l.mathers.fr",
    "https://l.mchome.net",
    "https://l.nulltext.org",
    "https://l.plabs.social",
    "https://l.roofo.cc",
    "https://l.twos.dev",
    "https://labdegato.com",
    "https://laguna.chat",
    "https://latte.isnot.coffee",
    "https://le-me.xyz",
    "https://le.fduck.net",
    "https://le.mnau.xyz",
    "https://leaf.dance",
    "https://leby.dev",
    "https://leddit.minnal.icu",
    "https://leddit.social",
    "https://lef.li",
    "https://lem.agoomem.xyz",
    "https://lem.amd.im",
    "https://lem.cochrun.xyz",
    "https://lem.elbullazul.com",
    "https://lem.free.as",
    "https://lem.lyk.pw",
    "https://lem.monster",
    "https://lem.ph3j.com",
    "https://lem.serkozh.me",
    "https://lem.simple-gear.com",
    "https://lem.southcape.social",
    "https://lemdit.com",
    "https://lemido.freakspot.net",
    "https://lemitar.meta1203.com",
    "https://lemiverse.xyz",
    "https://lemm.ee",
    "https://lemmerz.org",
    "https://lemmings.basic-domain.com",
    "https://lemmings.online",
    "https://lemmit.online",
    "https://lemmit.online",
    "https://lemmit.xyz",
    "https://lemmony.click",
    "https://lemmus.org",
    "https://lemmy",
    "https://lemmy",
    "https://lemmy",
    "https://lemmy",
    "https://lemmy-xqddz-u4892.vm.elestio.app",
    "https://lemmy.0x3d.uk",
    "https://lemmy.1204.org",
    "https://lemmy.2kd.de",
    "https://lemmy.4d2.org",
    "https://lemmy.6px.eu",
    "https://lemmy.86thumbs.net",
    "https://lemmy.aguiarvieira.pt",
    "https://lemmy.albertoluna.es",
    "https://lemmy.alexland.ca",
    "https://lemmy.amxl.com",
    "https://lemmy.amyjnobody.com",
    "https://lemmy.ananace.dev",
    "https://lemmy.andiru.de",
    "https://lemmy.anji.nl",
    "https://lemmy.anonion.social",
    "https://lemmy.antemeridiem.xyz",
    "https://lemmy.antisocial.ly",
    "https://lemmy.appeine.com",
    "https://lemmy.arclight.pro",
    "https://lemmy.astheriver.art",
    "https://lemmy.aucubin.de",
    "https://lemmy.austinite.online",
    "https://lemmy.austinvaness.com",
    "https://lemmy.austinwadeheller.com",
    "https://lemmy.avata.social",
    "https://lemmy.azamserver.com",
    "https://lemmy.barnacles.one",
    "https://lemmy.baswag.de",
    "https://lemmy.batlord.org",
    "https://lemmy.beebl.es",
    "https://lemmy.beru.co",
    "https://lemmy.best",
    "https://lemmy.blad.is",
    "https://lemmy.blahaj.zone",
    "https://lemmy.bleh.au",
    "https://lemmy.bloodmoon-network.de",
    "https://lemmy.blue",
    "https://lemmy.blugatch.tube",
    "https://lemmy.borlax.com",
    "https://lemmy.brad.ee",
    "https://lemmy.bradis.me",
    "https://lemmy.brief.guru",
    "https://lemmy.bringdaruck.us",
    "https://lemmy.browntown.dev",
    "https://lemmy.brynstuff.co.uk",
    "https://lemmy.bulwarkob.com",
    "https://lemmy.bunbi.net",
    "https://lemmy.burger.rodeo",
    "https://lemmy.burger.rodeo",
    "https://lemmy.burningboard.net",
    "https://lemmy.ca",
    "https://lemmy.cablepick.net",
    "https://lemmy.cafe",
    "https://lemmy.caffeinated.social",
    "https://lemmy.calebmharper.com",
    "https://lemmy.calvss.com",
    "https://lemmy.cat",
    "https://lemmy.chiisana.net",
    "https://lemmy.chromozone.dev",
    "https://lemmy.ciechom.eu",
    "https://lemmy.click",
    "https://lemmy.cloudhub.social",
    "https://lemmy.clueware.org",
    "https://lemmy.cmstactical.net",
    "https://lemmy.cnschn.com",
    "https://lemmy.cock.social",
    "https://lemmy.coeus.icu",
    "https://lemmy.comfysnug.space",
    "https://lemmy.commodore.social",
    "https://lemmy.cook.gg",
    "https://lemmy.coolmathgam.es",
    "https://lemmy.cornspace.space",
    "https://lemmy.corrigan.xyz",
    "https://lemmy.coupou.fr",
    "https://lemmy.croc.pw",
    "https://lemmy.cultimean.group",
    "https://lemmy.davidbuckley.ca",
    "https://lemmy.davidfreina.at",
    "https://lemmy.dbzer0.com",
    "https://lemmy.dcrich.net",
    "https://lemmy.deadca.de",
    "https://lemmy.death916.xyz",
    "https://lemmy.decronym.xyz",
    "https://lemmy.deev.io",
    "https://lemmy.dekay.se",
    "https://lemmy.demonoftheday.eu",
    "https://lemmy.devils.house",
    "https://lemmy.direktoratet.se",
    "https://lemmy.discothe.quest",
    "https://lemmy.dlgreen.com",
    "https://lemmy.dnet.social",
    "https://lemmy.donmcgin.com",
    "https://lemmy.doomeer.com",
    "https://lemmy.dork.lol",
    "https://lemmy.dormedas.com",
    "https://lemmy.douwes.co.uk",
    "https://lemmy.dudeami.win",
    "https://lemmy.dupper.net",
    "https://lemmy.dustybeer.com",
    "https://lemmy.dyslexicjedi.com",
    "https://lemmy.easfrq.live",
    "https://lemmy.eatsleepcode.ca",
    "https://lemmy.eco.br",
    "https://lemmy.edgarchirivella.com",
    "https://lemmy.efradaphi.de",
    "https://lemmy.eic.lu",
    "https://lemmy.einval.net",
    "https://lemmy.elest.io",
    "https://lemmy.elest.io",
    "https://lemmy.elmusfire.xyz",
    "https://lemmy.emopolarbear.com",
    "https://lemmy.enchanted.social",
    "https://lemmy.escapebigtech.info",
    "https://lemmy.eus",
    "https://lemmy.fakecake.org",
    "https://lemmy.fanboys.xyz",
    "https://lemmy.fauxreigner.net",
    "https://lemmy.fbxl.net",
    "https://lemmy.fdvrs.xyz",
    "https://lemmy.fedi.bub.org",
    "https://lemmy.fedihub.social",
    "https://lemmy.fediverse.jp",
    "https://lemmy.fediversum.de",
    "https://lemmy.film",
    "https://lemmy.finance",
    "https://lemmy.flauschbereich.de",
    "https://lemmy.flugratte.dev",
    "https://lemmy.fmhy.ml",
    "https://lemmy.foxden.party",
    "https://lemmy.foxden.social",
    "https://lemmy.freddeliv.me",
    "https://lemmy.fredhs.net",
    "https://lemmy.fribyte.no",
    "https://lemmy.friheter.com",
    "https://lemmy.fromshado.ws",
    "https://lemmy.frozeninferno.xyz",
    "https://lemmy.fucs.io",
    "https://lemmy.fun",
    "https://lemmy.funkyfish.cool",
    "https://lemmy.funkylab.xyz",
    "https://lemmy.fwgx.uk",
    "https://lemmy.fyi",
    "https://lemmy.g97.top",
    "https://lemmy.game-files.net",
    "https://lemmy.gareth.computer",
    "https://lemmy.ghostplanet.org",
    "https://lemmy.gjz010.com",
    "https://lemmy.glasgow.social",
    "https://lemmy.gmprojects.pro",
    "https://lemmy.graphics",
    "https://lemmy.graz.social",
    "https://lemmy.gross.hosting",
    "https://lemmy.grouchysysadmin.com",
    "https://lemmy.grygon.com",
    "https://lemmy.gsp8181.co.uk",
    "https://lemmy.gtfo.social",
    "https://lemmy.haigner.me",
    "https://lemmy.hamrick.xyz",
    "https://lemmy.helheim.net",
    "https://lemmy.helios42.de",
    "https://lemmy.hellwhore.com",
    "https://lemmy.help",
    "https://lemmy.helvetet.eu",
    "https://lemmy.holmosapien.com",
    "https://lemmy.hopskipjump.cloud",
    "https://lemmy.hosted.frl",
    "https://lemmy.hpost.no",
    "https://lemmy.hutch.chat",
    "https://lemmy.intai.tech",
    "https://lemmy.irrealis.net",
    "https://lemmy.isamp.com",
    "https://lemmy.iswhereits.at",
    "https://lemmy.itermori.de",
    "https://lemmy.iys.io",
    "https://lemmy.jacaranda.club",
    "https://lemmy.jacaranda.club",
    "https://lemmy.jamesj999.co.uk",
    "https://lemmy.jamestrey.com",
    "https://lemmy.jasondove.me",
    "https://lemmy.jasonsanta.xyz",
    "https://lemmy.javant.xyz",
    "https://lemmy.jigoku.us.to",
    "https://lemmy.jlh.name",
    "https://lemmy.jmtr.org",
    "https://lemmy.johnpanos.com",
    "https://lemmy.jpaulus.io",
    "https://lemmy.jpiolho.com",
    "https://lemmy.jstsmthrgk.eu",
    "https://lemmy.jtmn.dev",
    "https://lemmy.juggler.jp",
    "https://lemmy.k6qw.com",
    "https://lemmy.kagura.eu",
    "https://lemmy.karaolidis.com",
    "https://lemmy.katia.sh",
    "https://lemmy.kemomimi.fans",
    "https://lemmy.keychat.org",
    "https://lemmy.kghorvath.com",
    "https://lemmy.kizaing.ca",
    "https://lemmy.knocknet.net",
    "https://lemmy.ko4abp.com",
    "https://lemmy.kodeklang.social",
    "https://lemmy.korgen.xyz",
    "https://lemmy.koski.co",
    "https://lemmy.krobier.com",
    "https://lemmy.kutara.io",
    "https://lemmy.kya.moe",
    "https://lemmy.l00p.org",
    "https://lemmy.l0nax.org",
    "https://lemmy.legally-berlin.de",
    "https://lemmy.lemist.de",
    "https://lemmy.lif.ovh",
    "https://lemmy.link",
    "https://lemmy.linuxuserspace.show",
    "https://lemmy.littlejth.com",
    "https://lemmy.livesound.world",
    "https://lemmy.loomy.li",
    "https://lemmy.loungerat.io",
    "https://lemmy.loutsenhizer.com",
    "https://lemmy.lpcha.im",
    "https://lemmy.lucaslower.com",
    "https://lemmy.lukeog.com",
    "https://lemmy.lylapol.com",
    "https://lemmy.m1k.cloud",
    "https://lemmy.maatwo.com",
    "https://lemmy.macaddict89.me",
    "https://lemmy.mambastretch.com",
    "https://lemmy.maples.dev",
    "https://lemmy.mariusdavid.fr",
    "https://lemmy.marud.fr",
    "https://lemmy.mats.ooo",
    "https://lemmy.matthe815.dev",
    "https://lemmy.mazurka.xyz",
    "https://lemmy.mb-server.com",
    "https://lemmy.mbirth.uk",
    "https://lemmy.media",
    "https://lemmy.meissners.me",
    "https://lemmy.meli.dev",
    "https://lemmy.menos.gotdns.org",
    "https://lemmy.mentalarts.info",
    "https://lemmy.meowchat.xyz",
    "https://lemmy.meridiangrp.co.uk",
    "https://lemmy.mildgrim.com",
    "https://lemmy.mira.pm",
    "https://lemmy.ml",
    "https://lemmy.mlaga97.space",
    "https://lemmy.mlsn.fr",
    "https://lemmy.modshiftx.com",
    "https://lemmy.monster",
    "https://lemmy.moonling.nl",
    "https://lemmy.morrisherd.com",
    "https://lemmy.mpcjanssen.nl",
    "https://lemmy.mrm.one",
    "https://lemmy.munsell.io",
    "https://lemmy.mxh.nu",
    "https://lemmy.my.id",
    "https://lemmy.mypinghertz.com",
    "https://lemmy.mywire.xyz",
    "https://lemmy.n1ks.net",
    "https://lemmy.naga.sh",
    "https://lemmy.name",
    "https://lemmy.nanoklinika.tk",
    "https://lemmy.nathaneaston.com",
    "https://lemmy.nauk.io",
    "https://lemmy.neeley.cloud",
    "https://lemmy.nerdcave.us",
    "https://lemmy.nerdcore.social",
    "https://lemmy.nexus",
    "https://lemmy.nikore.net",
    "https://lemmy.nine-hells.net",
    "https://lemmy.ninja",
    "https://lemmy.nope.ly",
    "https://lemmy.nopro.be",
    "https://lemmy.norbz.org",
    "https://lemmy.notdead.net",
    "https://lemmy.nrd.li",
    "https://lemmy.nz",
    "https://lemmy.obrell.se",
    "https://lemmy.one",
    "https://lemmy.onitato.com",
    "https://lemmy.onlylans.io",
    "https://lemmy.otakufarms.com",
    "https://lemmy.parasrah.com",
    "https://lemmy.pastwind.top",
    "https://lemmy.pathoris.de",
    "https://lemmy.pcft.eu",
    "https://lemmy.pe1uca.dev",
    "https://lemmy.pec0ra.ch",
    "https://lemmy.perigrine.ca",
    "https://lemmy.philipcristiano.com",
    "https://lemmy.picote.ch",
    "https://lemmy.pineapplemachine.com",
    "https://lemmy.pineapplenest.com",
    "https://lemmy.pipe01.net",
    "https://lemmy.piperservers.net",
    "https://lemmy.pipipopo.pl",
    "https://lemmy.pit.ninja",
    "https://lemmy.place",
    "https://lemmy.plasmatrap.com",
    "https://lemmy.podycust.co.uk",
    "https://lemmy.podycust.co.uk",
    "https://lemmy.ppl.town",
    "https://lemmy.primboard.de",
    "https://lemmy.pro",
    "https://lemmy.productionservers.net",
    "https://lemmy.proxmox-lab.com",
    "https://lemmy.pryst.de",
    "https://lemmy.pt",
    "https://lemmy.pub",
    "https://lemmy.pubsub.fun",
    "https://lemmy.pussthecat.org",
    "https://lemmy.pwzle.com",
    "https://lemmy.pxm.nl",
    "https://lemmy.qpixel.me",
    "https://lemmy.quad442.com",
    "https://lemmy.radio",
    "https://lemmy.rat.academy",
    "https://lemmy.ravc.tech",
    "https://lemmy.recursed.net",
    "https://lemmy.remotelab.uk",
    "https://lemmy.rhymelikedi.me",
    "https://lemmy.riffel.family",
    "https://lemmy.rimkus.it",
    "https://lemmy.rollenspiel.monster",
    "https://lemmy.room409.xyz",
    "https://lemmy.roombob.cat",
    "https://lemmy.root6.de",
    "https://lemmy.rubenernst.dev",
    "https://lemmy.run",
    "https://lemmy.run",
    "https://lemmy.s9m.xyz",
    "https://lemmy.saik0.com",
    "https://lemmy.samad.one",
    "https://lemmy.sascamooch.com",
    "https://lemmy.sbs",
    "https://lemmy.scam-mail.me",
    "https://lemmy.scav1.com",
    "https://lemmy.schlunker.com",
    "https://lemmy.schmeisserweb.at",
    "https://lemmy.schuerz.at",
    "https://lemmy.scottlabs.io",
    "https://lemmy.sdf.org",
    "https://lemmy.sebbem.se",
    "https://lemmy.secnd.me",
    "https://lemmy.sedimentarymountains.com",
    "https://lemmy.seifert.id",
    "https://lemmy.selfhost.quest",
    "https://lemmy.selfip.org",
    "https://lemmy.server.fifthdread.com",
    "https://lemmy.services.coupou.fr",
    "https://lemmy.sh",
    "https://lemmy.shattervideoisland.com",
    "https://lemmy.sidh.bzh",
    "https://lemmy.sietch.online",
    "https://lemmy.skillissue.dk",
    "https://lemmy.smeargle.fans",
    "https://lemmy.snoot.tube",
    "https://lemmy.socdojo.com",
    "https://lemmy.soontm.de",
    "https://lemmy.spacestation14.com",
    "https://lemmy.sprawl.club",
    "https://lemmy.srv.eco",
    "https://lemmy.srv0.lol",
    "https://lemmy.staphup.nl",
    "https://lemmy.stark-enterprise.net",
    "https://lemmy.starlightkel.xyz",
    "https://lemmy.starmade.de",
    "https://lemmy.steken.xyz",
    "https://lemmy.stormlight.space",
    "https://lemmy.strandundmeer.net",
    "https://lemmy.stuart.fun",
    "https://lemmy.studio",
    "https://lemmy.suchmeme.nl",
    "https://lemmy.sumuun.net",
    "https://lemmy.sumuun.net",
    "https://lemmy.svc.vesey.tech",
    "https://lemmy.sweevo.net",
    "https://lemmy.syrasu.com",
    "https://lemmy.sysctl.io",
    "https://lemmy.tancomps.net",
    "https://lemmy.tanktrace.de",
    "https://lemmy.tario.org",
    "https://lemmy.tarsis.org",
    "https://lemmy.taubin.cc",
    "https://lemmy.teaisatfour.com",
    "https://lemmy.technosorcery.net",
    "https://lemmy.techstache.com",
    "https://lemmy.tedomum.net",
    "https://lemmy.telaax.com",
    "https://lemmy.tf",
    "https://lemmy.tgxn.net",
    "https://lemmy.thanatos.at",
    "https://lemmy.the-burrow.com",
    "https://lemmy.the-goblin.net",
    "https://lemmy.theia.cafe",
    "https://lemmy.themainframe.org",
    "https://lemmy.theonecurly.page",
    "https://lemmy.thepixelproject.com",
    "https://lemmy.therhys.co.uk",
    "https://lemmy.thesmokinglounge.club",
    "https://lemmy.thias.xyz",
    "https://lemmy.tillicumnet.com",
    "https://lemmy.timdn.com",
    "https://lemmy.timon.sh",
    "https://lemmy.timwaterhouse.com",
    "https://lemmy.tobyvin.dev",
    "https://lemmy.today",
    "https://lemmy.toot.pt",
    "https://lemmy.towards.vision",
    "https://lemmy.tr00st.co.uk",
    "https://lemmy.trippy.pizza",
    "https://lemmy.ubergeek77.chat",
    "https://lemmy.umainfo.live",
    "https://lemmy.uncomfortable.business",
    "https://lemmy.unfiltered.social",
    "https://lemmy.uninsane.org",
    "https://lemmy.utopify.org",
    "https://lemmy.utveckla.re",
    "https://lemmy.va-11-hall-a.cafe",
    "https://lemmy.vanoverloop.xyz",
    "https://lemmy.vepta.org",
    "https://lemmy.villa-straylight.social",
    "https://lemmy.vinodjam.com",
    "https://lemmy.vip",
    "https://lemmy.virtim.dev",
    "https://lemmy.vodkatonic.org",
    "https://lemmy.vrchat-dev.tech",
    "https://lemmy.vskr.net",
    "https://lemmy.vyizis.tech",
    "https://lemmy.w9r.de",
    "https://lemmy.webgirand.eu",
    "https://lemmy.website",
    "https://lemmy.weckhorst.no",
    "https://lemmy.weiser.social",
    "https://lemmy.whalesinspace.de",
    "https://lemmy.whynotdrs.org",
    "https://lemmy.wiuf.net",
    "https://lemmy.wizjenkins.com",
    "https://lemmy.world",
    "https://lemmy.wraithsquadrongaming.com",
    "https://lemmy.wtf",
    "https://lemmy.wxbu.de",
    "https://lemmy.wyattsmith.org",
    "https://lemmy.x01.ninja",
    "https://lemmy.xce.pt",
    "https://lemmy.xcoolgroup.com",
    "https://lemmy.xoynq.com",
    "https://lemmy.zelinsky.dev",
    "https://lemmy.zell-mbc.com",
    "https://lemmy.zip",
    "https://lemmy.zone",
    "https://lemmy.zroot.org",
    "https://lemmy2.addictmud.org",
    "https://lemmybedan.com",
    "https://lemmydeals.com",
    "https://lemmyfi.com",
    "https://lemmyfly.org",
    "https://lemmygrad.ml",
    "https://lemmygrid.com",
    "https://lemmyis.fun",
    "https://lemmyngs.social",
    "https://lemmynsfw.com",
    "https://lemmyonline.com",
    "https://lemmypets.xyz",
    "https://lemmyrs.org",
    "https://lemmyunchained.net",
    "https://lemmywinks.com",
    "https://lemmywinks.xyz",
    "https://lemnt.telaax.com",
    "https://lemthony.com",
    "https://lib.lgbt",
    "https://libreauto.app",
    "https://liminal.southfox.me",
    "https://link.fossdle.org",
    "https://linkage.ds8.zone",
    "https://linkopath.com",
    "https://links.decafbad.com",
    "https://links.hackliberty.org",
    "https://links.lowsec.club",
    "https://links.rocks",
    "https://links.roobre.es",
    "https://links.wageoffsite.com",
    "https://livy.one",
    "https://lm.bittervets.org",
    "https://lm.byteme.social",
    "https://lm.curlefry.net",
    "https://lm.electrospek.com",
    "https://lm.gsk.moe",
    "https://lm.halfassmart.net",
    "https://lm.inu.is",
    "https://lm.kalinowski.dev",
    "https://lm.korako.me",
    "https://lm.m0e.space",
    "https://lm.madiator.cloud",
    "https://lm.melonbread.dev",
    "https://lm.paradisus.day",
    "https://lm.put.tf",
    "https://lm.qtt.no",
    "https://lm.runnerd.net",
    "https://lm.sethp.cc",
    "https://lm.suitwaffle.com",
    "https://lm.williampuckering.com",
    "https://lmmy.io",
    "https://lmmy.net",
    "https://lmmy.tvdl.dev",
    "https://lmmy.ylwsgn.cc",
    "https://lmy.dotcomitsa.website",
    "https://lmy.drundo.com.au",
    "https://local106.com",
    "https://localghost.org",
    "https://localhost",
    "https://localhost",
    "https://localhost",
    "https://localhost",
    "https://localhost",
    "https://logophilia.net",
    "https://lolimbeer.com",
    "https://lostcheese.com",
    "https://lsmu.schmurian.xyz",
    "https://lucitt.social",
    "https://mander.xyz",
    "https://matejc.com",
    "https://matts.digital",
    "https://mayheminc.win",
    "https://mcr.town",
    "https://meganice.online",
    "https://melly.0x-ia.moe",
    "https://merv.news",
    "https://mesita.link",
    "https://midwest.social",
    "https://milksteak.org",
    "https://mindshare.space",
    "https://mlem.a-smol-cat.fr",
    "https://mobilemmohub.com",
    "https://monero.house",
    "https://monero.town",
    "https://monyet.cc",
    "https://moose.best",
    "https://moot.place",
    "https://moto.teamswollen.org",
    "https://mujico.org",
    "https://mydomain.ml",
    "https://mydomain.ml",
    "https://mydomain.ml",
    "https://mylem.my",
    "https://mylemmy.win",
    "https://narod.city",
    "https://negativenull.com",
    "https://neodrain.net",
    "https://netmonkey.tech",
    "https://news.cosocial.ca",
    "https://news.deghg.org",
    "https://news.idlestate.org",
    "https://nlemmy.nl",
    "https://no.lastname.nz",
    "https://nonewfriends.club",
    "https://normalcity.life",
    "https://notdigg.com",
    "https://notlemmy.notawebsite.fr",
    "https://notlemmy.site",
    "https://novoidspace.com",
    "https://nrsk.no",
    "https://nunu.dev",
    "https://nwdr.club",
    "https://occult.social",
    "https://oceanbreeze.earth",
    "https://odin.lanofthedead.xyz",
    "https://omg.qa",
    "https://opendmz.social",
    "https://orava.dev",
    "https://orzen.games",
    "https://outpost.zeuslink.net",
    "https://partizle.com",
    "https://pasta.faith",
    "https://pathfinder.social",
    "https://pathofexile-discuss.com",
    "https://pawb.social",
    "https://philly.page",
    "https://pootusmaximus.xyz",
    "https://popplesburger.hilciferous.nl",
    "https://poptalk.scrubbles.tech",
    "https://possumpat.io",
    "https://posta.no",
    "https://preserve.games",
    "https://programming.dev",
    "https://proit.org",
    "https://psychedelia.ink",
    "https://purrito.kamartaj.xyz",
    "https://pwzle.com",
    "https://quex.cc",
    "https://r-sauna.fi",
    "https://r.rosettast0ned.com",
    "https://r.stoi.cc",
    "https://r196.club",
    "https://rabbitea.rs",
    "https://radiation.party",
    "https://rammy.site",
    "https://rational-racoon.de",
    "https://rblind.com",
    "https://re.tei.li",
    "https://read.widerweb.org",
    "https://readit.space",
    "https://red.cyberhase.de",
    "https://reddit.moonbeam.town",
    "https://reddthat.com",
    "https://retarded.dev",
    "https://ripo.st",
    "https://rlyeh.cc",
    "https://rustyshackleford.cfd",
    "https://s.jape.work",
    "https://sambaspy.com",
    "https://scif6.nsalanparty.com",
    "https://seattlelunarsociety.org",
    "https://sedd.it",
    "https://seemel.ink",
    "https://selfhosted.forum",
    "https://sffa.community",
    "https://sh.itjust.works",
    "https://sha1.nl",
    "https://shinobu.cloud",
    "https://shitposting.monster",
    "https://shork.online",
    "https://sigmet.io",
    "https://silicon-dragon.com",
    "https://slangenettet.pyjam.as",
    "https://slrpnk.net",
    "https://sneakernet.social",
    "https://snkkis.me",
    "https://snuv.win",
    "https://soccer.forum",
    "https://social.coalition.space",
    "https://social.cyb3r.dog",
    "https://social.dn42.us",
    "https://social.fossware.space",
    "https://social.fr4me.io",
    "https://social.ggbox.fr",
    "https://social.hamington.net",
    "https://social.jears.at",
    "https://social.nerdhouse.io",
    "https://social.nerdswire.de",
    "https://social.nerdswire.de",
    "https://social.poisson.me",
    "https://social.sour.is",
    "https://social.vmdk.ca",
    "https://social2.blahajspin.lol",
    "https://solstice.etbr.top",
    "https://sopuli.xyz",
    "https://sowhois.gay",
    "https://spgrn.com",
    "https://stammtisch.hallertau.social",
    "https://stanx.page",
    "https://stars.leemoon.network",
    "https://startrek.website",
    "https://sub.rdls.dev",
    "https://sub.wetshaving.social",
    "https://sublight.one",
    "https://suppo.fi",
    "https://support.futbol",
    "https://support.futbol",
    "https://surlesworld.com",
    "https://szmer.info",
    "https://tabletop.place",
    "https://tagpro.lol",
    "https://talka.live",
    "https://techy.news",
    "https://tezzo.f0rk.pl",
    "https://thaumatur.ge",
    "https://thegarden-u4873.vm.elestio.app",
    "https://thegarden.land",
    "https://thegarden.land",
    "https://thelemmy.club",
    "https://theotter.social",
    "https://thepride.hexodine.com",
    "https://thesidewalkends.io",
    "https://thesimplecorner.org",
    "https://thevapor.space",
    "https://toast.ooo",
    "https://toons.zone",
    "https://tortoisewrath.com",
    "https://tslemmy.duckdns.org",
    "https://ttrpg.network",
    "https://tucson.social",
    "https://typemi.me",
    "https://upvote.au",
    "https://versalife.duckdns.org",
    "https://vlemmy.net",
    "https://voxpop.social",
    "https://wallstreets.bet",
    "https://waveform.social",
    "https://wayfarershaven.eu",
    "https://weiner.zone",
    "https://werm.social",
    "https://whata.clusterfsck.com",
    "https://whatyoulike.club",
    "https://whiskers.bim.boats",
    "https://wilbo.tech",
    "https://wirebase.org",
    "https://wired.bluemarch.art",
    "https://wizanons.dev",
    "https://wolfballs.com",
    "https://wumbo.buzz",
    "https://www.jrz.city",
    "https://www.korzekwa.io",
    "https://xffxe4.lol",
    "https://yall.theatl.social",
    "https://yiffit.net",
    "https://ymmel.nl",
    "https://yogibytes.page",
    "https://zemmy.cc",
    "https://zerobytes.monster",
    "https://zoo.splitlinux.org"
  ]);
  var INSTANCES_KBIN = /* @__PURE__ */ new Set([
    "https://champserver.net",
    "https://community.yshi.org",
    "https://feddit.online",
    "https://fedi196.gay",
    "https://fedia.io",
    "https://fediverse.boo",
    "https://forum.fail",
    "https://frmsn.space",
    "https://gehirneimer.de",
    "https://jlailu.social",
    "https://k.fe.derate.me",
    "https://karab.in",
    "https://kayb.ee",
    "https://kbin.buzz",
    "https://kbin.chat",
    "https://kbin.cocopoops.com",
    "https://kbin.dentora.social",
    "https://kbin.dk",
    "https://kbin.donar.dev",
    "https://kbin.fedi.cr",
    "https://kbin.korgen.xyz",
    "https://kbin.lgbt",
    "https://kbin.lol",
    "https://kbin.mastodont.cat",
    "https://kbin.melroy.org",
    "https://kbin.place",
    "https://kbin.possum.city",
    "https://kbin.projectsegfau.lt",
    "https://kbin.rocks",
    "https://kbin.run",
    "https://kbin.sh",
    "https://kbin.social",
    "https://kbin.tech",
    "https://kilioa.org",
    "https://kopnij.in",
    "https://longley.ws",
    "https://nadajnik.org",
    "https://nerdbin.social",
    "https://nolani.academy",
    "https://readit.buzz",
    "https://remy.city",
    "https://social.tath.link",
    "https://streetbikes.club",
    "https://teacup.social",
    "https://the.coolest.zone",
    "https://thebrainbin.org",
    "https://tuna.cat",
    "https://wiku.hu"
  ]);
  trace(`Define instances sets end`);

  // src/our-changes.js
  var OUR_CHANGES = { addedNodes: {} };
  function getAddedNodesSelectors() {
    return Object.values(OUR_CHANGES.addedNodes);
  }
  function registerAddedNode(id, selector) {
    OUR_CHANGES.addedNodes[id] = selector;
  }

  // src/constants.js
  var constants_default = {
    ICON_CLASS: withNS(`icon`),
    ICON_LOADING_CLASS: withNS(`loading`),
    ICON_STYLES_ID: withNS(`icon-styles`),
    ICON_LINK_CLASS: withNS(`icon-link`),
    ICON_LINK_SYMBOL_ID: withNS(`icon-link-symbol`),
    ICON_SPINNER_CLASS: withNS(`icon-spinner`),
    ICON_SPINNER_SYMBOL_ID: withNS(`icon-spinner-symbol`),
    ORIGINAL_LINK_CLASS: withNS(`original-link`),
    SHOW_AT_HOME_BUTTON_ID: withNS(`show-at-home`),
    MAKE_HOME_BUTTON_ID: withNS(`make-home`),
    ICON_SVG_TEMPLATE_ID: withNS(`icon-template`),
    AUTH_WRONG: `AUTH_WRONG`,
    AUTH_MISSING: `AUTH_MISSING`,
    REWRITE_STATUS: withNSCamelCase(`localUrlStatus`),
    REWRITE_STATUS_PENDING: `pending`,
    REWRITE_STATUS_SUCCESS: `success`,
    REWRITE_STATUS_ERROR: `error`,
    REWRITE_STATUS_UNRESOLVED: `unresolved`,
    SETUP_AUTH_MESSAGE: `Lemmy Universal Link Switcher: Visit your home instance once to set up post/comment rewriting`
  };
  function withNS(identifier) {
    return `lemmy-rewrite-urls-` + identifier;
  }
  function withNSCamelCase(identifier) {
    return `lemmyRewriteUrls` + identifier.charAt(0).toUpperCase() + identifier.slice(1);
  }

  // src/rewriting/helpers.js
  function isHashLink(link) {
    return link.hash && link.origin + link.pathname + link.search === location.origin + location.pathname + location.search;
  }
  function isSamePage(url1, url2) {
    return url1.host === url2.host && url1.pathname === url2.pathname;
  }
  function isV17() {
    return isoData?.site_res?.version.startsWith(`0.17`);
  }
  var stopEventHandler = (event) => {
    event.preventDefault();
    event.stopPropagation();
  };

  // src/rewriting/auth.js
  var AUTH;
  function getAuthFromCookie() {
    return document.cookie.split("; ").find((row) => row.startsWith("jwt="))?.split("=")[1];
  }
  async function setAuth(auth) {
    AUTH = auth;
    await GM.setValue(`auth`, auth);
  }
  async function initAuth() {
    const curAuth = await getAuth();
    if (curAuth) {
      AUTH = curAuth;
      return;
    }
    if (location.origin === HOME) {
      const newAuth = getAuthFromCookie();
      await setAuth(newAuth);
      if (newAuth && await GM.getValue(`authNoticeShown`)) {
        alert(`Lemmy Universal Link Switcher: Post/comment rewriting has been set up successfully`);
        await GM.setValue(`authNoticeShown`, null);
      }
    } else if (HOME && !await GM.getValue(`authNoticeShown`)) {
      await GM.setValue(`authNoticeShown`, `true`);
      alert(constants_default.SETUP_AUTH_MESSAGE);
    }
  }
  function updateAuthPeriodically() {
    setInterval(async () => {
      const prev = AUTH;
      const newAuth = location.origin === HOME ? getAuthFromCookie() : await getAuth();
      if (prev !== newAuth) {
        debug(`Auth changed`);
        await setAuth(newAuth);
        clearMissingUrlsInCache();
        triggerRewrite();
      }
    }, 1234);
  }
  async function getAuth() {
    return await GM.getValue(`auth`);
  }

  // src/rewriting/url-mapping.js
  function splitPaths(url) {
    return url.pathname.split(`/`).slice(1);
  }
  function isRemoteLemmyUrl(url) {
    return url.origin !== HOME && isLemmyInstance(url);
  }
  function isRemoteKbinUrl(url) {
    return url.origin !== HOME && isKbinInstance(url);
  }
  function isRemoteUrl(url) {
    return isRemoteLemmyUrl(url) || isRemoteKbinUrl(url);
  }
  function findLocalUrlForStandardAtFormat(url, rootPath) {
    const paths = splitPaths(url);
    const name = paths[1].includes(`@`) ? paths[1] : paths[1] + `@` + url.host;
    return `${HOME}/${rootPath || paths[0]}/${name}` + url.search + url.hash;
  }
  function findLocalUrlForLemmyUrl(url) {
    if (isLemmyUserOrCommunityUrl(url)) {
      return findLocalUrlForStandardAtFormat(url);
    } else {
      return null;
    }
  }
  function findLocalUrlForKbinUserUrl(url) {
    const paths = splitPaths(url);
    const user = paths[1].startsWith(`@`) ? paths[1].substring(1) : paths[1];
    const name = user.includes(`@`) ? user : user + `@` + url.host;
    return `${HOME}/u/${name}` + url.search + url.hash;
  }
  function findLocalUrlForKbinUrl(url) {
    if (isKbinMagazineUrl(url)) {
      return findLocalUrlForStandardAtFormat(url, mappedKbinRootPath(url));
    } else if (isKbinUserUrl(url)) {
      return findLocalUrlForKbinUserUrl(url);
    } else {
      return null;
    }
  }
  function findLocalUrl(url) {
    if (isRemoteLemmyUrl(url))
      return findLocalUrlForLemmyUrl(url);
    if (isRemoteKbinUrl(url))
      return findLocalUrlForKbinUrl(url);
    return null;
  }
  function parseResponse(response) {
    try {
      return JSON.parse(response.response);
    } catch (e) {
      debug(`Error parsing response JSON`, e);
      return response.response;
    }
  }
  function logRequest(response, data) {
    trace(
      `FinalUrl`,
      response.finalUrl,
      `status`,
      response.status,
      `text`,
      response.statusText,
      `response`,
      data || response.response
    );
    trace(`responseHeaders`, response.responseHeaders);
  }
  function performXmlHttpRequest(url, doneCallback) {
    GM.xmlHttpRequest({
      url,
      onloadend: (response) => {
        const data = parseResponse(response);
        logRequest(response, data);
        doneCallback(response, data);
      }
    });
  }
  async function fetchApIdFromRemote(url) {
    const endpoint = isLemmyPostUrl(url) ? `post` : `comment`;
    const paths = splitPaths(url);
    const id = paths[1];
    return new Promise((resolve, reject) => {
      performXmlHttpRequest(`${url.origin}/api/v3/${endpoint}?id=${id}`, (response, data) => {
        const apId = data[`${endpoint}_view`]?.[endpoint]?.ap_id;
        if (response.status === 200 && apId) {
          resolve(apId);
        } else {
          handleFailedRequest(`fetching AP ID`, response, reject);
        }
      });
    });
  }
  function handleFailedRequest(requestName, response, reject) {
    if (response.status >= 200 && response.status <= 299) {
      reject(`${requestName}: Unhandled successful response, status: ${response.status}`);
    } else if (response.status >= 400 && response.status <= 599) {
      reject(`${requestName}: Error, status: ${response.status}`);
    } else {
      reject(`${requestName}: Something weird happened, status: ${response.status}`);
    }
  }
  async function resolveObjectFromHome(url) {
    return new Promise(async (resolve, reject) => {
      const auth = await getAuth();
      if (!auth) {
        debug(`No auth token found`);
        reject(constants_default.AUTH_MISSING);
      }
      performXmlHttpRequest(
        `${HOME}/api/v3/resolve_object?auth=${auth}&q=${encodeURIComponent(url.href)}`,
        (response, data) => {
          if (response.status === 200 && data.post?.post?.id) {
            resolve(`${HOME}/post/${data.post.post.id}${url.search}${url.hash}`);
          } else if (response.status === 200 && data.comment?.comment?.id) {
            resolve(`${HOME}/comment/${data.comment.comment.id}${url.search}${url.hash}`);
          } else if (response.status === 400 && data?.error === `couldnt_find_object`) {
            resolve(null);
          } else if (response.status === 400 && data?.error === `not_logged_in`) {
            reject(constants_default.AUTH_WRONG);
          } else {
            handleFailedRequest(`resolving object`, response, reject);
          }
        }
      );
    });
  }
  var urlCache = {};
  function clearMissingUrlsInCache() {
    for (const value of Object.values(urlCache)) {
      if (value.error)
        delete value.error;
      if (value.localUrl === null)
        delete value.localUrl;
    }
  }
  function getCacheKey(url) {
    return url.host + url.pathname + url.search;
  }
  function cacheResult(url, localUrl) {
    const key = getCacheKey(url);
    if (!urlCache[key]) {
      urlCache[key] = {};
    }
    if (urlCache[key].error)
      delete urlCache[key].error;
    urlCache[key].localUrl = localUrl;
    return localUrl;
  }
  function cacheErrorResult(url, error) {
    const key = getCacheKey(url);
    if (!urlCache[key]) {
      urlCache[key] = {};
    }
    urlCache[key].error = error;
  }
  function getLocalUrlfromCache(url) {
    const key = getCacheKey(url);
    if (urlCache[key]?.error) {
      throw urlCache[key]?.error;
    } else {
      return urlCache[key]?.localUrl;
    }
  }
  async function fetchLocalUrl(url, loadFromCache = true) {
    if (loadFromCache) {
      const cached = getLocalUrlfromCache(url);
      if (cached !== void 0) {
        trace(`Found URL ${url} in cache: ${cached}`);
        return cached;
      }
    }
    try {
      return cacheResult(url, await fetchLocalUrlNoCache(url));
    } catch (e) {
      debug(`fetchLocalUrl error`, e);
      cacheErrorResult(url, e);
      throw e;
    }
  }
  async function fetchLocalUrlNoCache(url) {
    trace(`Trying to resolve URL ${url} directly`);
    const localUrl = await resolveObjectFromHome(url);
    if (localUrl !== null) {
      return localUrl;
    } else {
      trace(`Did not find URL ${url} directly`);
    }
    const apId = new URL(await fetchApIdFromRemote(url));
    trace(`Found AP ID for URL ${url}: ${apId}`);
    if (!apId.search) {
      apId.search = url.search;
    }
    if (!apId.hash) {
      apId.hash = url.hash;
    }
    if (isSamePage(url, apId)) {
      trace(`Previous URL was AP ID already, URL not federated for some reason`);
      return null;
    } else {
      return await resolveObjectFromHome(apId);
    }
  }
  function isInstantlyRewritable(url) {
    return isRemoteLemmyUrl(url) && isLemmyUserOrCommunityUrl(url) || isRemoteKbinUrl(url) && (isKbinMagazineUrl(url) || isKbinUserUrl(url));
  }
  function isRewritableAfterResolving(url) {
    return isRemoteLemmyUrl(url) && (isLemmyPostUrl(url) || isLemmyCommentUrl(url));
  }
  function isLemmyPostUrl(url) {
    const paths = splitPaths(url);
    return paths[0] === `post`;
  }
  function isLemmyCommentUrl(url) {
    const paths = splitPaths(url);
    return paths[0] === `comment`;
  }
  function isLemmyUserOrCommunityUrl(url) {
    const paths = splitPaths(url);
    return paths[0] === `c` || paths[0] === `u`;
  }
  function isKbinPostUrl(url) {
    const paths = splitPaths(url);
    return paths[0] === `m` && paths.length > 2 && paths[2] === `t`;
  }
  function isKbinMicroblogUrl(url) {
    const paths = splitPaths(url);
    return paths[0] === `m` && paths.length > 2 && paths[2] === `p`;
  }
  function isKbinMicroblogOverviewUrl(url) {
    const paths = splitPaths(url);
    return paths[0] === `m` && paths.length > 2 && paths[2] === `microblog`;
  }
  function isKbinMagazinePeopleUrl(url) {
    const paths = splitPaths(url);
    return paths[0] === `m` && paths.length > 2 && paths[2] === `people`;
  }
  function isKbinMagazineUrl(url) {
    const paths = splitPaths(url);
    return paths[0] === `m` && !isKbinPostUrl(url) && !isKbinMagazinePeopleUrl(url) && !isKbinMicroblogUrl(url) && !isKbinMicroblogOverviewUrl(url);
  }
  function mappedKbinRootPath(url) {
    const paths = splitPaths(url);
    if (paths[0] === `m`) {
      return `c`;
    } else {
      return null;
    }
  }
  function isKbinUserUrl(url) {
    const paths = splitPaths(url);
    return paths.length === 2 && paths[0] === `u`;
  }

  // src/rewriting/links/icon.js
  function getIcon(link) {
    return link.querySelector(`.` + constants_default.ICON_CLASS);
  }
  function createIcon(link) {
    ensureTemplateAvailable();
    ensureIconStylesAdded();
    const wrapper = document.createElement(`span`);
    registerAddedNode(constants_default.ICON_CLASS, `.` + constants_default.ICON_CLASS);
    wrapper.classList.add(constants_default.ICON_CLASS);
    if (link.children.length === 0 || getComputedStyle(link.children[link.children.length - 1]).marginRight === `0px`) {
      wrapper.style.marginLeft = `0.5em`;
    }
    const linkIcon = createSVG();
    linkIcon.classList.add(constants_default.ICON_LINK_CLASS);
    linkIcon.innerHTML = `<use href=#${constants_default.ICON_LINK_SYMBOL_ID} />`;
    wrapper.append(linkIcon);
    const spinnerIcon = createSVG();
    spinnerIcon.classList.add(constants_default.ICON_SPINNER_CLASS);
    spinnerIcon.innerHTML = `<use href=#${constants_default.ICON_SPINNER_SYMBOL_ID} />`;
    wrapper.append(spinnerIcon);
    return wrapper;
  }
  function createSVG() {
    return document.createElementNS(`http://www.w3.org/2000/svg`, `svg`);
  }
  function ensureTemplateAvailable() {
    if (document.querySelector(`#` + constants_default.ICON_SVG_TEMPLATE_ID))
      return;
    const template = createSVG();
    template.id = constants_default.ICON_SVG_TEMPLATE_ID;
    template.innerHTML = `<defs>
<symbol id=${constants_default.ICON_LINK_SYMBOL_ID} viewBox="0 0 100 100"><path d="M52.8 34.6c.8.8 1.8 1.2 2.8 1.2s2-.4 2.8-1.2c1.5-1.5 1.5-4 0-5.6l-5.2-5.2h26v30.6c0 2.2 1.8 3.9 3.9 3.9 2.2 0 3.9-1.8 3.9-3.9V19.8c0-2.2-1.8-3.9-3.9-3.9h-30l5.2-5.2c1.5-1.5 1.5-4 0-5.6s-4-1.5-5.6 0l-11.8 12c-1.5 1.5-1.5 4 0 5.6l11.9 11.9zM31.1 28.7V11c0-3-2.5-5.5-5.5-5.5H8C5 5.5 2.5 8 2.5 11v17.7c0 3 2.5 5.5 5.5 5.5h17.7c3 0 5.4-2.5 5.4-5.5zM47.2 65.4c-1.5-1.5-4-1.5-5.6 0s-1.5 4 0 5.6l5.2 5.2h-26V45.6c0-2.2-1.8-3.9-3.9-3.9S13 43.5 13 45.6v34.5c0 2.2 1.8 3.9 3.9 3.9h30l-5.2 5.2c-1.5 1.5-1.5 4 0 5.6.8.8 1.8 1.2 2.8 1.2s2-.4 2.8-1.2l11.9-11.9c1.5-1.5 1.5-4 0-5.6l-12-11.9zM92 65.8H74.4c-3 0-5.5 2.5-5.5 5.5V89c0 3 2.5 5.5 5.5 5.5H92c3 0 5.5-2.5 5.5-5.5V71.3c0-3-2.5-5.5-5.5-5.5z"/></symbol>
<symbol id=${constants_default.ICON_SPINNER_SYMBOL_ID} viewBox="0 0 32 32"><path d="M16 32c-4.274 0-8.292-1.664-11.314-4.686s-4.686-7.040-4.686-11.314c0-3.026 0.849-5.973 2.456-8.522 1.563-2.478 3.771-4.48 6.386-5.791l1.344 2.682c-2.126 1.065-3.922 2.693-5.192 4.708-1.305 2.069-1.994 4.462-1.994 6.922 0 7.168 5.832 13 13 13s13-5.832 13-13c0-2.459-0.69-4.853-1.994-6.922-1.271-2.015-3.066-3.643-5.192-4.708l1.344-2.682c2.615 1.31 4.824 3.313 6.386 5.791 1.607 2.549 2.456 5.495 2.456 8.522 0 4.274-1.664 8.292-4.686 11.314s-7.040 4.686-11.314 4.686z"/></symbol>
</defs>`;
    registerAddedNode(constants_default.ICON_SVG_TEMPLATE_ID, `#` + constants_default.ICON_SVG_TEMPLATE_ID);
    document.head.append(template);
  }
  function ensureIconStylesAdded() {
    if (document.querySelector(`#` + constants_default.ICON_STYLES_ID))
      return;
    const style = document.createElement(`style`);
    style.id = constants_default.ICON_STYLES_ID;
    style.innerText = `
	.${constants_default.ICON_SPINNER_CLASS} {
		display: none;
		animation: spins 2s linear infinite;
	}
	.${constants_default.ICON_LINK_CLASS} {
		display: inline-block;
	}
	.${constants_default.ICON_LOADING_CLASS} > .${constants_default.ICON_LINK_CLASS} {
		display: none;
	}
	.${constants_default.ICON_LOADING_CLASS} > .${constants_default.ICON_SPINNER_CLASS} {
		display: inline-block;
	}
	.${constants_default.ICON_CLASS} > svg {
		vertical-align: sub;
		height: 1em; width: 1em;
		stroke: currentColor;
		fill: currentColor;
	}`;
    registerAddedNode(constants_default.ICON_STYLES_ID, `#` + constants_default.ICON_STYLES_ID);
    document.head.append(style);
  }

  // src/tippy.js
  var tippy_default = window.tippy;

  // src/rewriting/links/tooltip.js
  function getOriginalLinkHtml(originalHref) {
    registerAddedNode(constants_default.ORIGINAL_LINK_CLASS, `.` + constants_default.ORIGINAL_LINK_CLASS);
    return `Original link: <a class="${constants_default.ORIGINAL_LINK_CLASS}" href="${originalHref}">${originalHref}</a>`;
  }
  function defaultOptions(link) {
    return {
      appendTo: () => link.parentNode,
      allowHTML: true,
      interactive: true,
      animation: false,
      placement: "bottom",
      hideOnClick: false
    };
  }
  function createOriginalLinkTooltip(link, originalHref) {
    trace(`Create original link tooltip`, link, originalHref);
    getIcon(link).addEventListener(`click`, stopEventHandler);
    return createLinkTooltip(link, getOriginalLinkHtml(originalHref));
  }
  function createLinkTooltip(link, content) {
    return tippy_default(getIcon(link), {
      ...defaultOptions(link),
      content
    });
  }
  function createLinkLoadTooltip(link) {
    trace(`Create link load tooltip`, link);
    getIcon(link).classList.add(constants_default.ICON_LOADING_CLASS);
    return createLinkTooltip(link, `Loading home URL...<br />Don't want to wait? ${getOriginalLinkHtml(link.href)}`);
  }
  function linkLoadTooltipSuccess(tooltip, originalHref) {
    linkLoadResult(tooltip, `\u2714\uFE0F Changed link to home instance`, getOriginalLinkHtml(originalHref));
  }
  function linkLoadTooltipError(tooltip, error) {
    linkLoadResult(tooltip, `\u274C  ` + error);
  }
  function linkLoadResult(tooltip, result, finalContent = result) {
    const icon = tooltip.reference;
    icon.classList.remove(constants_default.ICON_LOADING_CLASS);
    if (tooltip.state.isVisible) {
      tooltip.setContent(result);
      setTimeout(() => {
        tooltip.hide();
        tooltip.setContent(finalContent);
      }, 2e3);
    } else {
      tooltip.setContent(finalContent);
    }
  }

  // src/rewriting/links/links.js
  function changeLinkHref(link, localUrl) {
    const treeWalker = document.createTreeWalker(link, NodeFilter.SHOW_TEXT, (node) => {
      if (node.textContent.toLowerCase().trim() === link.href.toLowerCase().trim()) {
        return NodeFilter.FILTER_ACCEPT;
      } else {
        return NodeFilter.FILTER_SKIP;
      }
    });
    let textNode;
    while ((textNode = treeWalker.nextNode()) !== null) {
      textNode.textContent = localUrl;
    }
    link.href = localUrl;
    link.addEventListener(`click`, (event) => {
      if (event.button === 0 && !event.ctrlKey && link.target !== `_blank`) {
        location.href = localUrl;
      }
    });
  }
  function appendIconTo(elem, icon) {
    if (elem.children.length === 0 || getComputedStyle(elem.children[elem.children.length - 1]).display !== `inline-block`) {
      elem.append(icon);
    } else {
      appendIconTo(elem.children[elem.children.length - 1], icon);
    }
  }
  function addFetchLocalUrlHandler(link) {
    let tooltip;
    const handler = async (event) => {
      if (event.type === `click`) {
        stopEventHandler(event);
        if (tooltip)
          tooltip.show();
        return;
      }
      link.removeEventListener(`focus`, handler);
      link.removeEventListener(`mouseenter`, handler);
      if (link.dataset[constants_default.REWRITE_STATUS] === constants_default.REWRITE_STATUS_PENDING)
        return;
      link.dataset[constants_default.REWRITE_STATUS] = constants_default.REWRITE_STATUS_PENDING;
      tooltip = createLinkLoadTooltip(link);
      try {
        const localUrl = await fetchLocalUrl(link);
        if (!localUrl) {
          debug(`Local URL for ${link.href} could not be found`);
          linkLoadTooltipError(tooltip, `Home URL could not be found`);
          return;
        }
        trace(`Local URL for ${link.href} found: ${localUrl}`);
        const oldHref = link.href;
        changeLinkHref(link, localUrl);
        linkLoadTooltipSuccess(tooltip, oldHref);
        link.dataset[constants_default.REWRITE_STATUS] = constants_default.REWRITE_STATUS_SUCCESS;
      } catch (e) {
        debug(`Error while trying to resolve local URL`, e);
        let msg;
        if (e === constants_default.AUTH_WRONG) {
          msg = `Saved login expired. Return to your home instance and log in again.`;
        } else if (e === constants_default.AUTH_MISSING) {
          msg = constants_default.SETUP_AUTH_MESSAGE;
        } else {
          msg = `Error while trying to find home URL`;
        }
        linkLoadTooltipError(tooltip, msg);
        link.dataset[constants_default.REWRITE_STATUS] = constants_default.REWRITE_STATUS_ERROR;
      } finally {
        link.removeEventListener(`click`, handler);
      }
    };
    link.addEventListener(`click`, handler);
    link.addEventListener(`focus`, handler);
    link.addEventListener(`mouseenter`, handler);
  }
  function isFediverseLink(link) {
    const svg = link.querySelector(`svg`);
    if (!svg)
      return false;
    if (svg.children.length === 0)
      return false;
    return svg.children[0].getAttribute(`xlink:href`)?.includes(`#icon-fedilink`);
  }
  function rewriteToLocal(link) {
    if (!link.parentNode)
      return false;
    if (link.classList.contains(constants_default.ORIGINAL_LINK_CLASS))
      return false;
    if (link.dataset[constants_default.REWRITE_STATUS] === constants_default.REWRITE_STATUS_SUCCESS)
      return false;
    if (isHashLink(link))
      return false;
    if (!isRemoteUrl(link))
      return false;
    if (isFediverseLink(link))
      return false;
    if (isInstantlyRewritable(link)) {
      const localUrl = findLocalUrl(link);
      if (!localUrl)
        return false;
      if (isSamePage(new URL(localUrl), location))
        return false;
      const oldHref = link.href;
      changeLinkHref(link, localUrl);
      const icon = createIcon(link);
      appendIconTo(link, icon);
      createOriginalLinkTooltip(link, oldHref);
      link.dataset[constants_default.REWRITE_STATUS] = constants_default.REWRITE_STATUS_SUCCESS;
      trace(`Rewrite link`, link, ` from`, oldHref, `to`, localUrl);
      return true;
    } else if (isRewritableAfterResolving(link)) {
      if (!getIcon(link)) {
        appendIconTo(link, createIcon(link));
      }
      if (!link.dataset[constants_default.REWRITE_STATUS]) {
        link.dataset[constants_default.REWRITE_STATUS] = constants_default.REWRITE_STATUS_UNRESOLVED;
        addFetchLocalUrlHandler(link);
      }
    }
  }
  function findLinksInChange(change) {
    if (change.type === `childList`) {
      const links = Array.from(change.addedNodes).flatMap((addedNode) => {
        if (addedNode.tagName?.toLowerCase() === `a`) {
          return addedNode;
        } else if (addedNode.querySelectorAll) {
          return Array.from(addedNode.querySelectorAll(`a`));
        } else {
          return [];
        }
      });
      if (links.length > 0)
        trace(`Change`, change, `contained the links`, links);
      return links;
    } else if (change.type === `attributes`) {
      return change.target.matches?.(`a`) ? change.target : [];
    } else {
      return [];
    }
  }
  function findLinksToRewrite(changes) {
    if (!changes) {
      return document.querySelectorAll(`a`);
    }
    return changes.flatMap(findLinksInChange);
  }
  async function rewriteLinksToLocal(changes) {
    const links = findLinksToRewrite(changes);
    const chunkSize = 50;
    return await async function processChunk(currentChunk) {
      const startIdx = currentChunk * chunkSize;
      const endChunkIdx = (currentChunk + 1) * chunkSize;
      const endIdx = Math.min(links.length, endChunkIdx);
      debug(
        `Processing ${links.length} links, current chunk `,
        currentChunk,
        `processing links ${startIdx} to ${endIdx}`
      );
      let anyRewritten = false;
      for (let i = startIdx; i < endIdx; ++i) {
        const rewritten = rewriteToLocal(links[i]);
        anyRewritten = anyRewritten || rewritten;
      }
      debug(`Processed links ${startIdx} to ${endIdx}`);
      if (endChunkIdx >= links.length) {
        return anyRewritten;
      }
      const chunkResult = await new Promise((resolve) => setTimeout(async () => {
        resolve(await processChunk(currentChunk + 1));
      }, 0));
      return anyRewritten || chunkResult;
    }(0);
  }

  // src/rewriting/make-home.js
  function addMakeHomeButton() {
    if (document.querySelector(`#` + constants_default.MAKE_HOME_BUTTON_ID))
      return false;
    if (!isRemoteLemmyUrl(location) || location.pathname !== `/settings`)
      return false;
    const insertAfter = document.querySelector(`#user-password`)?.closest(`.card`);
    if (!insertAfter)
      return;
    const button = document.createElement(`button`);
    button.id = constants_default.MAKE_HOME_BUTTON_ID;
    button.setAttribute(`class`, `btn btn-block btn-primary mr-4 w-100`);
    button.innerText = `Make this my home instance for URL rewriting`;
    button.addEventListener(`click`, () => {
      setHome(location.origin);
      button.remove();
    });
    registerAddedNode(constants_default.MAKE_HOME_BUTTON_ID, `#` + constants_default.MAKE_HOME_BUTTON_ID);
    insertAfter.insertAdjacentElement("afterend", button);
    return true;
  }

  // src/rewriting/show-at-home.js
  function showAtHomeButtonText() {
    const host = new URL(HOME).hostname;
    return `Show on ${host}`;
  }
  function createShowAtHomeAnchor(localUrl) {
    const showAtHome = document.createElement(`a`);
    showAtHome.dataset.creationHref = location.href;
    showAtHome.id = constants_default.SHOW_AT_HOME_BUTTON_ID;
    showAtHome.innerText = showAtHomeButtonText();
    showAtHome.href = localUrl;
    registerAddedNode(constants_default.SHOW_AT_HOME_BUTTON_ID, `#` + constants_default.SHOW_AT_HOME_BUTTON_ID);
    return showAtHome;
  }
  function addLemmyShowAtHomeButton(localUrl) {
    const logo = document.querySelector(`a.navbar-brand`);
    const navbarIcons = isV17() ? document.querySelector(`[title="Search"]`)?.closest(`.navbar-nav`) : document.querySelector(`#navbarIcons`);
    if (!logo || !navbarIcons) {
      debug(`Could not find position to insert ShowAtHomeButton at`);
      return false;
    }
    const mobile = createShowAtHomeAnchor(localUrl);
    mobile.classList.add(`d-md-none`);
    mobile.style[`margin-right`] = `8px`;
    mobile.style[`margin-left`] = `auto`;
    if (isV17()) {
      document.querySelector(`.navbar-nav.ml-auto`)?.classList.remove(`ml-auto`);
    }
    logo.insertAdjacentElement("afterend", mobile);
    const desktop = createShowAtHomeAnchor(localUrl);
    desktop.classList.add(`d-md-inline`);
    desktop.style[`margin-right`] = `8px`;
    navbarIcons.insertAdjacentElement("beforebegin", desktop);
    return true;
  }
  function addKbinShowAtHomeButton(localUrl) {
    const prependTo = document.querySelector(`#header menu:not(.head-nav__menu)`);
    if (!prependTo) {
      debug(`Could not find position to insert ShowAtHomeButton at`);
      return false;
    }
    const item = document.createElement(`li`);
    item.append(createShowAtHomeAnchor(localUrl));
    prependTo.prepend(item);
    return true;
  }
  function addButton(localUrl) {
    const oldButton = document.querySelector(`#` + constants_default.SHOW_AT_HOME_BUTTON_ID);
    if (oldButton && oldButton.dataset.creationHref !== location.href) {
      debug(`Removing old show at home button`);
      oldButton.remove();
    } else if (oldButton) {
      debug(`Old show at home button still exists`);
      return false;
    }
    if (!localUrl) {
      debug(`No local URL for show at home button found`);
      return false;
    } else if (isRemoteLemmyUrl(location)) {
      return addLemmyShowAtHomeButton(localUrl);
    } else if (isRemoteKbinUrl(location)) {
      return addKbinShowAtHomeButton(localUrl);
    } else {
      return false;
    }
  }
  async function addShowAtHomeButton() {
    if (isInstantlyRewritable(location)) {
      return addButton(findLocalUrl(location));
    } else if (isRewritableAfterResolving(location)) {
      try {
        return addButton(await fetchLocalUrl(location));
      } catch (e) {
        debug(`Error while trying to add "show at home" button`, e);
      }
    }
  }

  // src/rewriting/rewrite.js
  function triggerRewrite() {
    doAllDomChanges();
  }
  function isOrHasOurAddedNode(node) {
    return getAddedNodesSelectors().some((selector) => node.matches?.(selector) || node.querySelector?.(selector));
  }
  function isIrrelevantChange(change) {
    if (change.type === `childList`) {
      if (Array.from(change.removedNodes).some(isOrHasOurAddedNode)) {
        trace(`Change`, change, `is relevant because a removed node is/has ours`);
        return false;
      }
      if (!Array.from(change.addedNodes).every(isOrHasOurAddedNode)) {
        trace(`Change`, change, `is relevant because not every added node is/has ours`);
        return false;
      }
    } else if (change.type === `attributes` && isRemoteUrl(new URL(change.target.href))) {
      trace(`Change`, change, `is relevant because href changed to a remote URL`);
      return false;
    }
    trace(`Change`, change, `is irrelevant`);
    return true;
  }
  async function startRewriting() {
    new MutationObserver((changes, observer) => {
      debug(`MutationObserver triggered`, changes);
      if (changes.every(isIrrelevantChange)) {
        debug(`All observed changes are irrelevant`);
        return;
      }
      doAllDomChanges(changes);
    }).observe(document.body, {
      subtree: true,
      childList: true,
      attributeFilter: [`href`]
    });
    await doAllDomChanges();
  }
  async function doAllDomChanges(changes) {
    debug(`doAllDomChanges start`);
    const addedMakeHomeButton = addMakeHomeButton();
    if (addedMakeHomeButton)
      debug(`Added Make Home Button`);
    const addedShowAtHomeButton = HOME ? addShowAtHomeButton() : false;
    if (addedShowAtHomeButton)
      debug(`Added Show At Home Button`);
    const rewrittenLinks = HOME ? await rewriteLinksToLocal(changes) : false;
    if (rewrittenLinks)
      debug(`Rewritten some links`);
    debug(`doAllDomChanges end`);
  }

  // src/gm.js
  async function setValue(key, value) {
    await GM.setValue(key, value);
  }
  async function getValue(key) {
    return await GM.getValue(key);
  }

  // src/home.js
  var HOME;
  async function initHome() {
    HOME = await getValue(`home`);
    if (!HOME && isLemmyInstance(location) && confirm(`Lemmy Universal Link Switcher: Set this instance to be your home instance to which all URLs get rewritten to?`)) {
      setHome(location.origin);
    }
  }
  async function setHome(newHome) {
    if (typeof newHome !== `string`) {
      newHome = null;
    }
    HOME = newHome;
    await setValue(`home`, newHome);
  }
  async function getHome() {
    return await getValue(`home`);
  }
  function updateHomePeriodically() {
    debug(`Current HOME`, HOME);
    setInterval(async () => {
      const prev = HOME;
      await setHome(await getHome());
      if (prev !== HOME) {
        debug(`HOME changed from`, prev, `to`, HOME);
        triggerRewrite();
      }
    }, 1337);
  }

  // src/main.js
  (async () => {
    await initHome();
    updateHomePeriodically();
    await initAuth();
    updateAuthPeriodically();
    startRewriting();
  })();
})();